使用SetBinding的Xamarin.Forms绑定无法正常工作

时间:2015-08-19 09:42:36

标签: 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); }
    }
}

我派生自这个类并设置Binding上下文:

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

这是视图模型:

 public class FeedbackViewModel : BaseViewModel
 {
     private string header;

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

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

当我运行它时 - 标题不会绑定到viewmodel的属性。 有什么明显的东西我忘记了吗?或者我做错了什么?

2 个答案:

答案 0 :(得分:1)

由于您不共享XAML的{​​{1}}部分,因此我们只能猜测,但让我们尝试一下:

你说:

  

标头不绑定到viewmodel的属性

我非常确定(来自您共享的代码)FeedbackView Header属性设置,即使您的绑定方式是非常规的。这是问题吗?或者你的问题是你没有在屏幕上显示任何内容?

解决"没有显示任何内容"问题需要对代码进行一些更改。首先,在TabItem

上设置propertyChanged arg
BindableProperty.Create

实现它,并创建一个虚拟方法,以便您可以在子视图中覆盖它

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

现在,在您的衍生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; } ctor中设置Binding是非常规的。它打破了MVVM模式,因为View(TabItem)对ViewModel的结构做了一些假设(并且存在Header属性)。

该绑定通常在TabItem继承的实例上设置。

TabItem

或者,当作为ctor参数传递VM已经打破 MVVM时,您最终可以在var feedback = new FeedbackView (myVm); feedback.SetBinding (TabItem.HeaderProperty, "Header"); ctor中执行此操作。

最后一部分是我的拙见。不要对它进行激烈的讨论,或者在没有我参与的情况下进行讨论:)

答案 1 :(得分:0)

您对BindableProperty的实施是错误的。在这里查看如何正确执行:https://blog.xamarin.com/using-custom-controls-in-xamarin.forms-on-android/

该属性的Binding通常在Page内完成。在那里,您将ViewModel的属性绑定到控件的BindableProperty。你不是在控件本身内部做的。