繁体   English   中英

将相对源根父控件的属性绑定到子类的附加属性 - 使应用程序崩溃

[英]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);
}

我可能会使用以下内容,但我认为这是一个坏主意,当EntryBindingContext与其中一个根父级不同时它是无用的,而且它看起来也不灵活:

...
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM