diff options
author | Samantha Houts <samantha@teamredwall.com> | 2016-04-12 11:35:01 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-04-12 11:35:00 -0700 |
commit | 73defe491f11fc417a22eebcf805ee20df90045a (patch) | |
tree | 82d5587119d509c45837fd651381d24d824e39fd | |
parent | 76c8c57fb30621272e19d493787836ed8c322b9d (diff) | |
download | xamarin-forms-73defe491f11fc417a22eebcf805ee20df90045a.tar.gz xamarin-forms-73defe491f11fc417a22eebcf805ee20df90045a.tar.bz2 xamarin-forms-73defe491f11fc417a22eebcf805ee20df90045a.zip |
[Core] Can bind properties in BindableObjects added to static resources in XAML (#58)
Resources that are `BindableObject`s will inherit the `Parent`'s `BindingContext` unless they are `Element`s that have non-null `Parent`s.
5 files changed, 160 insertions, 1 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml new file mode 100644 index 00000000..d207cd23 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" ?> +<local:TestContentPage xmlns="http://xamarin.com/schemas/2014/forms" + xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" + xmlns:test="clr-namespace:Xamarin.Forms.Controls.Issues" + xmlns:local="clr-namespace:Xamarin.Forms.Controls" + x:Class="Xamarin.Forms.Controls.Issues.Bugzilla23942"> + + <local:TestContentPage.Resources> + <ResourceDictionary> + <test:Bugzilla23942Options x:Key="opts" + Text="{Binding DoesItWork}" /> + </ResourceDictionary> + </local:TestContentPage.Resources> + + <local:TestContentPage.Content> + <StackLayout> + <test:Bugzilla23942Label x:Name="label" Options="{DynamicResource opts}" /> + </StackLayout> + </local:TestContentPage.Content> + +</local:TestContentPage>
\ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml.cs new file mode 100644 index 00000000..efa78941 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla23942.xaml.cs @@ -0,0 +1,111 @@ +using Xamarin.Forms; +using Xamarin.Forms.CustomAttributes; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 23942, "Cannot bind properties in BindableObjects added to static resources in XAML", PlatformAffected.All)] + public partial class Bugzilla23942 : TestContentPage + { + [Preserve(AllMembers = true)] + public class TestViewModel : ViewModelBase + { + string _doesItWork; + public string DoesItWork + { + get + { + return _doesItWork; + } + set + { + _doesItWork = value; + OnPropertyChanged(); + } + } + } + +#if APP + public Bugzilla23942() + { + InitializeComponent(); + } +#endif + + private void InitializeView() + { + TestViewModel vm = new TestViewModel() { DoesItWork = "initial binding works" }; + BindingContext = vm; + vm.DoesItWork = "success"; + } + + protected override void Init() + { + InitializeView(); + } + + protected override void OnAppearing() + { + base.OnAppearing(); + var lbl = this.FindByName<Bugzilla23942Label>("label"); + lbl.Text = lbl.Options.Text; + } + +#if UITEST + [Test] + public void Bugzilla23942Test() + { + RunningApp.WaitForElement(q => q.Marked("success")); + } +#endif + } + + [Preserve(AllMembers = true)] + public class Bugzilla23942Options : BindableObject + { + public static readonly BindableProperty TextProperty = + BindableProperty.Create(propertyName: nameof(Text), + returnType: typeof(string), + declaringType: typeof(Bugzilla23942Options), + defaultValue: default(string)); + + public string Text + { + get + { + return (string)GetValue(TextProperty); + } + set + { + SetValue(TextProperty, value); + } + } + } + + [Preserve(AllMembers = true)] + public class Bugzilla23942Label : Label + { + public static readonly BindableProperty OptionsProperty = + BindableProperty.Create(propertyName: nameof(Options), + returnType: typeof(Bugzilla23942Options), + declaringType: typeof(Bugzilla23942Label), + defaultValue: default(Bugzilla23942Options)); + + public Bugzilla23942Options Options + { + get + { + return (Bugzilla23942Options)GetValue(OptionsProperty); + } + set + { + SetValue(OptionsProperty, value); + } + } + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index ca43a273..6a1e0b93 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -18,6 +18,9 @@ <DependentUpon>Bugzilla22229.xaml</DependentUpon> </Compile> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla22401.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Bugzilla23942.xaml.cs"> + <DependentUpon>Bugzilla23942.xaml</DependentUpon> + </Compile> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla24769.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla25234.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla25662.cs" /> @@ -516,6 +519,12 @@ </EmbeddedResource> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla23942.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:UpdateDesignTimeXaml</Generator> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> <EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla39636.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:UpdateDesignTimeXaml</Generator> diff --git a/Xamarin.Forms.Core/BindableObject.cs b/Xamarin.Forms.Core/BindableObject.cs index 683d390a..f3482004 100644 --- a/Xamarin.Forms.Core/BindableObject.cs +++ b/Xamarin.Forms.Core/BindableObject.cs @@ -360,7 +360,7 @@ namespace Xamarin.Forms if (fromStyle) context.Attributes |= BindableContextAttributes.IsSetFromStyle; - // else ommitted on purpose + // else omitted on purpose bool currentlyApplying = _applying; diff --git a/Xamarin.Forms.Core/Element.cs b/Xamarin.Forms.Core/Element.cs index a85bb3fb..b6312737 100644 --- a/Xamarin.Forms.Core/Element.cs +++ b/Xamarin.Forms.Core/Element.cs @@ -17,6 +17,8 @@ namespace Xamarin.Forms string _automationId; + IList<BindableObject> _bindableResources; + List<Action<object, ResourcesChangedEventArgs>> _changeHandlers; List<KeyValuePair<string, BindableProperty>> _dynamicResources; @@ -321,6 +323,12 @@ namespace Xamarin.Forms SetChildInheritedBindingContext(child, bc); } + if (_bindableResources != null) + foreach (BindableObject item in _bindableResources) + { + SetInheritedBindingContext(item, BindingContext); + } + base.OnBindingContextChanged(); } @@ -420,6 +428,8 @@ namespace Xamarin.Forms handler(this, new ResourcesChangedEventArgs(values)); if (_dynamicResources == null) return; + if (_bindableResources == null) + _bindableResources = new List<BindableObject>(); foreach (KeyValuePair<string, object> value in values) { List<BindableProperty> changedResources = null; @@ -434,6 +444,14 @@ namespace Xamarin.Forms continue; foreach (BindableProperty changedResource in changedResources) OnResourceChanged(changedResource, value.Value); + + var bindableObject = value.Value as BindableObject; + if (bindableObject != null && (bindableObject as Element)?.Parent == null) + { + if (!_bindableResources.Contains(bindableObject)) + _bindableResources.Add(bindableObject); + SetInheritedBindingContext(bindableObject, BindingContext); + } } } |