WPF - 自定义控件的依赖项 属性 在 2 路模式下丢失绑定

WPF - Dependency Property of Custom Control lost Binding at 2 way mode

我有这个自定义控件

XAML:

<UserControl x:Class="WpfApplication1.UC"
             ...
             x:Name="uc">
    <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal">
        <TextBox Text="{Binding Test, ElementName=uc}" Width="50" HorizontalAlignment="Left"/>
    </StackPanel>
</UserControl>

C#

public partial class UC : UserControl
{
    public static readonly DependencyProperty TestProperty;

    public string Test
    {
        get
        {
            return (string)GetValue(TestProperty);
        }
        set
        {
            SetValue(TestProperty, value);
        }
    }

    static UC()
    {
        TestProperty = DependencyProperty.Register("Test",typeof(string),
                      typeof(UC), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    }

    public UC()
    {
        InitializeComponent();
    }
}

这就是我使用自定义控件的方式:

<DockPanel>
    <ItemsControl ItemsSource="{Binding Path=DataList}"
                  DockPanel.Dock="Left">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding}" CommandParameter="{Binding}" Click="Button_Click"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    <local:UC Test="{Binding SelectedString, Mode=OneWay}"/>
</DockPanel>

--

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<string> _dataList;
    public ObservableCollection<string> DataList
    {
        get { return _dataList; }
        set
        {
            _dataList = value;
            OnPropertyChanged("DataList");
        }
    }

    private string _selectedString;
    public string SelectedString
    {
        get { return _selectedString; }
        set
        {
            _selectedString = value;
            OnPropertyChanged("SelectedString");
        }
    }

    public MainWindow()
    {
        InitializeComponent();

        this.DataList = new ObservableCollection<string>();
        this.DataList.Add("1111");
        this.DataList.Add("2222");
        this.DataList.Add("3333");
        this.DataList.Add("4444");

        this.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.SelectedString = (sender as Button).CommandParameter.ToString();
    }
}

如果我不更改 UC 的文本,一切正常。当我单击左侧面板中的每个按钮时,按钮的内容显示在 UC.

但是当我更改 UC 的文本(例如:更改为 9999)时,Test 属性 失去了绑定。当我单击左侧面板中的每个按钮时,UC 的文本与更改后的文本相同 (9999)。在调试中,我看到 SelectedString 会因每次单击按钮而改变,但 UC 的文本不会。

我可以 'fix' 这个问题,方法是在 UC 中使用这个 <TextBox Text="{Binding Test, ElementName=uc, Mode=OneWay}" Width="50" HorizontalAlignment="Left"/>

但是我只是想弄明白问题所在,请问有人能帮我解释一下吗

设置单向绑定的目标值会清除绑定。绑定 <TextBox Text="{Binding Test, ElementName=uc}" 是双向的,当文本更改时它也会更新测试 属性。但是测试 属性 是单向绑定的目标,并且该绑定已被清除。

您的 'fix' 之所以有效,是因为作为单向绑定,它从不更新测试并且从不清除绑定。根据您的需要,您还可以将 UC 绑定更改为 <local:UC Test="{Binding SelectedString, Mode=TwoWay}"/> 当通过其他方法更新源或目标时,不会清除双向绑定。

下一行有问题

 <local:UC Test="{Binding SelectedString, Mode=OneWay}"/>

模式设置为 SelectString 绑定的单向模式,因此当代码库中的值发生变化时,文本将被更新。更改源 属性 或目标 属性 以自动将绑定源更新为 TwoWay

   <local:UC Test="{Binding SelectedString, Mode=TwoWay}"/>