c# - 使用 SetBinding 的 Xamarin.Forms 绑定(bind)不起作用

标签 c# mvvm data-binding xamarin xamarin.forms

我有基本的自定义控件:

public class TabItem : ContentView
{
    public TabItem()
    {
        SetBinding(HeaderProperty, new Binding("Header"));
    }

    public static readonly BindableProperty HeaderProperty =
        BindableProperty.Create("Header", typeof(string), typeof(TabItem), default(string));

    public string Header
    {
        get { return (string)GetValue(TabItem.HeaderProperty); }
        set { SetValue(TabItem.HeaderProperty, value); }
    }
}

我派生自此类并设置绑定(bind)上下文:

public partial class FeedbackView : TabItem
{
   public FeedbackView(FeedbackViewModel viewModel)
   {
       InitializeComponent();    
       Content.BindingContext = viewModel;    
   }
}

这是 View 模型:

 public class FeedbackViewModel : BaseViewModel
 {
     private string header;

     public FeedbackViewModel()
     {
         Header = "Test Header";
     }

     public string Header
     {
         get { return header; }
         set
         {
             header = value;
             OnPropertyChanged("Header");
         }
      }

当我运行它时 - header 未绑定(bind)到 View 模型的属性。 有什么明显的我忘记了吗?还是我做错了什么?

最佳答案

由于您没有共享 FeedbackViewXAML 部分,因此只能猜测,但我们还是要试试:

你说:

header not binds to viewmodel's property

我非常确定(根据您共享的代码)TabItemHeader 属性已设置,即使您进行绑定(bind)的方式是非常规的。这是问题吗?或者您的问题是屏幕上没有显示任何内容?

解决“无显示”问题需要对您的代码进行一些更改。首先,在 BindableProperty.Create

上设置 propertyChanged 参数
public static readonly BindableProperty HeaderProperty =
    BindableProperty.Create("Header", typeof(string), typeof(TabItem), default(string),
    propertyChanged: OnHeaderChanged);

实现它,并创建一个虚拟方法,这样你就可以在你的 subview 中覆盖它

static void OnHeaderChanged (BindableObject bindable, object oldValue, object newvalue)
{
    ((TabItem)bindable).OnHeaderChanged ((string)oldValue, (string)newValue);
}

protected virtual void OnHeaderChanged (string oldValue, string newValue)
{
}

现在,在您派生的 FeedbackView 中,您可以覆盖 OnHeaderChanged 并根据 Header 设置标签

protected override void OnHeaderChanged (string oldValue, string newValue)
{
    //headerLabel is defined in Xaml, and has a x:Name="headerLabel"
    headerLabel.Text = newValue;
}

这应该可以帮助您入门。

最后一点,我要说的是,在 TabItem 构造函数中设置 Binding 是非常规的。它打破了 MVVM 模式,因为 View (TabItem) 对 ViewModel 的结构(以及 Header 属性的存在)做出了一些假设。

该绑定(bind)通常在 TabItem 继承实例上设置。

var feedback = new FeedbackView (myVm);
feedback.SetBinding (TabItem.HeaderProperty, "Header");

或者,由于将 VM 作为 ctor 参数传递已经中断 MVVM,您最终可以在 FeedbackView ctor 中执行此操作。

这最后一部分是我的拙见。不要对此展开激烈的讨论,也不要在没有我参与的情况下进行:)

关于c# - 使用 SetBinding 的 Xamarin.Forms 绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32091902/

相关文章:

c# - 生成mysql表主键字符串+数字的最佳方式

c# - WPF 样式不适用于运行时(但适用于设计器)

c# - 如何在 C# 单元测试中涵盖图像转换?

c# - 以编程方式在 TabItem 中加载 UserControl

c# - 如何从 ViewModel 调用 TreeView 上的焦点

c# - 数据绑定(bind)不适用于 Avalondock 窗口

c# - 为什么 KeyDown 事件无法访问绑定(bind)变量的当前值?

c# - 使用 include 不会改变行为

c# - ViewModel在页面上为Null

asp.net - WPF 中 ASP.NET DataBind() 的替代方案是什么?