[英]Binding a property of a relative source root parent control to an attached property of a child class - crash the app
我正在尝试将Entry
控件的附加属性绑定到它的根父级的属性,该属性是ContentView
:(主要是为了使用/访问NumBehaviors
类中被调用视图的 ViewModel(BindingContext))应用程序甚至在启动之前就崩溃了在调试中没有明确的问题点:
由于对象的当前状态,操作无效。
在 Xamarin.Forms.Binding.ApplyRelativeSourceBinding (Xamarin.Forms.BindableObject targetObject, Xamarin.Forms.BindableProperty targetProperty) [0x00041] 在 D:\\a\\1\\s\\Xamarin.Forms.Core\\ Binding.cs:153
[错误] 致命的未处理异常:System.InvalidOperationException:由于对象的当前状态,操作无效。
1-我做错了什么(可能是BindingContext
)? 或者是 Xamarin 仍然不能像 wpf 那样处理绑定(比如缺少ElementName
)?
2- 为什么调试错误/异常不是那么明确?
主视图.xaml :
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:Helpers="clr-namespace:App.Helpers"
xmlns:Behaviors="clr-namespace:App.Behaviors"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center"
x:Class="App.Views.MainView">
<Entry>
<Entry.Behaviors>
<Behaviors:NumBehaviors Helpers:HelperClass.Vm=
"{Binding Source={RelativeSource AncestorType={x:Type ContentView}}, Path=VM}"/>
</Entry.Behaviors>
</Entry>
HelperClass.cs
public static BindableProperty VmProperty =
BindableProperty.Create("Vm", typeof(object), typeof(HelperClass), null);
public static object GetVm(BindableObject bindable)
{
return (object)bindable.GetValue(VmProperty);
}
public static void SetVm(BindableObject bindable, object value)
{
bindable.SetValue(VmProperty, value);
}
主视图文件
public object VM {get; set;}
public MainView()
{
InitializeComponent();
VM = (object) new MyViewModel();
BindingContext = VM;
}
NumBehaviors.cs
...
void OnEntryTextChanged(object sender, TextChangedEventArgs args) {
var usedvm = HelperClass.GetVm((BindableObject)sender);
}
我可能会使用以下内容,但我认为这是一个坏主意,当Entry
的BindingContext
与其中一个根父级不同时它是无用的,而且它看起来也不灵活:
...
void OnEntryTextChanged(object sender, TextChangedEventArgs args) {
var usedvm = ((Entry)sender).BindingContext;
}
PS:也许我的方法不好,我愿意接受更好的方法来实现这一目标。
编辑
使用Xamarin.Forms 4.8.0.1364
还尝试使用AncestorType={x:Type local:MainView}}
而不是AncestorType={x:Type ContentView}}
给出了相同的结果。
也许这与 Xamarin.Forms [Bug] Compiled bindings not working when using AncestorType #9839 的这个打开的问题有关
避免此问题的另一种解决方案是简单地通过将 Attached 属性从<Entry.Behaviors:NumBehaviors>
到<Entry>
来更改设计:
<Entry Helpers:HelperClass.Vm="{Binding Source={RelativeSource AncestorType={x:Type ContentView}},
Path=VM}">
<Entry.Behaviors>
<Behaviors:NumBehaviors/>
</Entry.Behaviors>
</Entry>
此举也将修复我在我的问题的代码犯了错,我是物业安装Vm
对象<Entry.Behaviors:NumBehaviors>
当我试图从对象得到它Sender(=Entry)
( var usedvm = HelperClass.GetVm((BindableObject)sender);
) 将始终返回null
。
RelativeSource
可以找到其祖先的绑定上下文,但行为不在当前可视化树中。
我建议使用它来指示绑定上下文:
Command="{Binding BindingContext.YourCommand, Source={x:Reference PageName}}"
YourCommand
必须可以从BindingContext
访问,并且PageName
必须在封闭ContentPage
的属性中设置,如<ContentPage ... x:Name="PageName"
可以在此处找到更多详细信息。 来自那个链接的人的道具,他给出了最初的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.