C# Xamarin.使用SetBinding的表单绑定不起作用

C# Xamarin.使用SetBinding的表单绑定不起作用,c#,mvvm,data-binding,xamarin,xamarin.forms,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

我有基本自定义控件:

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); }
    }
}
我从该类派生并设置绑定上下文:

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的属性。
有什么明显的事情我忘了吗?或者我做错了什么?

您对
BindableProperty
的实现是错误的。请看这里如何正确操作:


对属性的
绑定通常在
页面
内完成。在这里,您可以将
ViewModel
的属性绑定到控件的
BindableProperty
。你不能在控件内部进行操作

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

你说:

标头未绑定到viewmodel的属性

我很确定(从您共享的代码中)设置了
TabItem
Header
属性,即使您执行绑定的方式是非常规的。这就是问题所在吗?或者你们的问题是你们并没有在屏幕上显示任何东西

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

公共静态只读BindableProperty头属性=
Create(“Header”、typeof(string)、typeof(TabItem)、default(string),
更改的属性:OnHeaderChanged);
实现它,并创建一个虚拟方法,以便可以在子视图中重写它

静态无效OnHeaderChanged(BindableObject bindable、object oldValue、object newvalue)
{
((TabItem)bindable).OnHeaderChanged((字符串)oldValue,(字符串)newValue);
}
受保护的虚拟void OnHeaderChanged(字符串oldValue、字符串newValue)
{
}
现在,在派生的
反馈视图中
,您可以覆盖
OnHeaderChanged
,并根据
标题设置标签

受保护的覆盖无效OnHeaderChanged(字符串oldValue、字符串newValue)
{
//headerLabel是在Xaml中定义的,它有一个x:Name=“headerLabel”
headerLabel.Text=newValue;
}
这应该让你开始

最后,我要说的是,在
TabItem
ctor中设置绑定是非常不传统的。当视图(TabItem)对ViewModel的结构(以及Header属性的存在)做出一些假设时,它打破了MVVM模式

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

var反馈=新反馈视图(myVm);
feedback.SetBinding(TabItem.HeaderProperty,“标题”);
或者,由于将VM作为ctor参数传递已经破坏了MVVM,您最终可以在
FeedbackView
ctor中这样做


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

看来您忘记在
反馈视图模型中实现
INotifyPropertyChanged
@Wosi抱歉,我忘记了我的
FeedbackViewModel
派生自
BaseViewModel
类,其中
INotifyPropertyChanged
已经实现。我编辑有问题的代码。为什么我不能在控件内部定义绑定?我还更新了有问题的代码。现在是否正确?控件不知道有关
ViewModel
的任何信息。绑定属性的名称对于
BindableProperty
不重要。否则,只能将
TextView.TextProperty
绑定到名为
text
的属性,而不能将其绑定到
CustomerServiceWModel.LastName
UserViewModel.EmailAddress
。绑定在
页面
或其
XAML
文件中完成。这是
ViewModel
Control
之间的连接。所以您的实现仍然是错误的。阅读这篇博客文章,你会发现其中的区别。