C# 无法绑定viewmodel属性-我自己的用户控件(WPF)

C# 无法绑定viewmodel属性-我自己的用户控件(WPF),c#,wpf,mvvm,controls,C#,Wpf,Mvvm,Controls,这个问题是众所周知和流行的 今天我浏览了很多帖子,但是没有一个能让我解决问题,所以我决定向你寻求帮助。我想我遵循了其他用户的所有提示 CustomControl.xaml: MainViewModel.cs: MainUserControl.xaml 在MainUserControl.xaml文件中,我有三个StackPanel。第一个是我想要实现的目标。不幸的是,当前没有绑定任何数据,也没有显示任何内容 但是,当我为属性指定一个字符串值而不是绑定时,文本将正确显示在示例2中 示例3:当我创建到

这个问题是众所周知和流行的

今天我浏览了很多帖子,但是没有一个能让我解决问题,所以我决定向你寻求帮助。我想我遵循了其他用户的所有提示

CustomControl.xaml:

MainViewModel.cs:

MainUserControl.xaml

在MainUserControl.xaml文件中,我有三个StackPanel。第一个是我想要实现的目标。不幸的是,当前没有绑定任何数据,也没有显示任何内容

但是,当我为属性指定一个字符串值而不是绑定时,文本将正确显示在示例2中

示例3:当我创建到例如textblock组件的绑定时,文本也将显示。。。第一个stackpanel名称NotWorking中只有一个控件的工作方式不同


您看到错误了吗?

问题在于您在MainUserControl中设置datacontext的行:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

当您在代码中设置DataContext时,MainUserControl中的绑定将在CustomControl中而不是在MainViewModel中查找名为Test的属性。

UserControl不能设置自己的DataContext。请注意,对TextBlock的Text属性进行双向绑定是没有意义的。这种绑定本质上是单向的。因此,设置UpdateSourceTrigger=PropertyChanged也是毫无意义的。
public partial class CustomControl : UserControl
{
    public static readonly DependencyProperty FirstNameProperty = DependencyProperty.Register(
        "FirstName",
        typeof(string),
        typeof(CustomControl),
        new FrameworkPropertyMetadata(default(string),
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public string FirstName
    {
        get
        {
            return (string)GetValue(FirstNameProperty);
        }
        set
        {
            SetValue(FirstNameProperty, value);
        }
    }

    public CustomControl()
    {
        InitializeComponent();
    }
}
    private string _test;
    public string Test
    {
        get { return _test; }
        set
        {
            _test = value;
            OnPropertyChanged(string.Empty);
        }
    }

    public MainViewModel()
    {
        Test = "abc";
    }

    public new event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
<StackPanel x:Name="NotWorking">
      <userControls:CustomControl FirstName="{Binding Path=Test, Mode=TwoWay}" />
</StackPanel>

<StackPanel x:Name="Working">
      <userControls:CustomControl FirstName="My string value that works" />
</StackPanel>

<StackPanel x:Name="WorkingToo">
      <TextBlock Text="{Binding Path=Test, Mode=TwoWay}" />
</StackPanel>
DataContext="{Binding RelativeSource={RelativeSource Self}}"