Entry
控件的附加属性绑定到其根父级的属性上,该父级是一个 ContentView
:
(主要是为了在 NumBehaviors
类中使用/访问调用视图的 ViewModel(BindingContext))
应用程序在调试过程中没有明显的问题,但在启动之前崩溃:
由于对象的当前状态,操作无效。
在 Xamarin.Forms.Binding.ApplyRelativeSourceBinding (Xamarin.Forms.BindableObject targetObject, Xamarin.Forms.BindableProperty targetProperty) [0x00041] in D:\a\1\s\Xamarin.Forms.Core\ Binding.cs:153 中
[ERROR] 致命未处理异常: System.InvalidOperationException: 由于对象的当前状态,操作无效。
1- 我是否做错了什么(可能是使用了BindingContext
)?还是Xamarin在处理绑定方面还没有像WPF一样好(例如缺少ElementName
)?
2- 为什么调试错误/异常不是那么明显?
MainView.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);
}
MainView.cs
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
Helpers:HelperClass.Vm..
应该是 <Entry.. 的附加属性,而不是Entry.Behaviors:NumBehaviors
,否则HelperClass.GetVm((BindableObject)sender);
将始终返回 null,除非我们以某种方式提供Sender.Behaviors:NumBehaviors
作为参数,而不是 sender (=Entry)。 - Cfun