WPF - 自定义控件的依赖属性在双向​​模式下丢失绑定

时间:2015-10-27 17:00:03

标签: wpf data-binding custom-controls dependency-properties

我有这个自定义控件

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的文本不是。

我可以使用<TextBox Text="{Binding Test, ElementName=uc, Mode=OneWay}" Width="50" HorizontalAlignment="Left"/>中的UC来解决此问题。

但我只是想了解这个问题,有人可以帮我解释一下。

2 个答案:

答案 0 :(得分:2)

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

您的修复&#39;因为作为OneWay绑定,它永远不会更新Test,并且永远不会清除绑定。根据您的需要,您还可以将UC绑定更改为<local:UC Test="{Binding SelectedString, Mode=TwoWay}"/>当通过其他方法更新源或目标时,不会清除双向绑定。

答案 1 :(得分:0)

问题在于以下行

SelectString

将模式设置为TwoWay绑定的单向模式,以便在代码库中的值更改时更新文本。更改源属性或目标属性以自动将绑定源更新为 <local:UC Test="{Binding SelectedString, Mode=TwoWay}"/>

{{1}}