wpf 依赖属性没有更新我的用户控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4182165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:19:16  来源:igfitidea点击:

Dependency Property is not updating my Usercontrol

wpfbindingdependency-properties

提问by Ashish Ashu

The line below works for the TextBox DP Text, where CellNo is a property of a class which derives from INotifyPropertychanged. So here when I change the CellNo the Text will be updated and When I change the CellNo the Text will be updated. This will work fine.

下面的行适用于 TextBox DP Text,其中 CellNo 是派生自 INotifyPropertychanged 的​​类的属性。因此,当我更改 CellNo 时,文本将更新,而当我更改 CellNo 时,文本将更新。这将正常工作。

Text="{Binding Path = CellNo, Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}"

I have create a user control which contain only one TextBox. I have defined one DP name CellValue as below:

我创建了一个仅包含一个 TextBox 的用户控件。我定义了一个 DP 名称 CellValue 如下:

public string CellValue
    {
        get { return (string)GetValue(CellValueProperty); }
        set { SetValue(CellValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for LimitValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CellValueProperty =
        DependencyProperty.Register("CellValue", typeof(string), typeof(control), new FrameworkPropertyMetadata
        {
            BindsTwoWayByDefault = true,
        });

Now when I use this user control in any dialog and do the same binding as above, the Target ( TextBox inside User control) is NOT updating.

现在,当我在任何对话框中使用此用户控件并执行与上述相同的绑定时,目标(用户控件内的文本框)不会更新。

 <local:control
        x:Name="control" 
        CellValue="{Binding Path = CellNo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

Also inside user control I have binded the Text Property of TextBox to CellValue DP.

同样在用户控件中,我已将 TextBox 的 Text 属性绑定到 CellValue DP。

Inside User control

内部用户控件

<TextBox                 
        Text="{Binding Path = CellValue}"
        Name="textBox2" />

I want when the CellValue changes the TextBox Text should also be updated, but with the above appoach it remains blank.

我希望当 CellValue 更改时 TextBox 文本也应该更新,但使用上述方法它保持空白。

回答by Fredrik Hedblad

This code

这段代码

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

is trying to bind against the Property CellNo of the UserControl. Add RelativeSource or ElementName and it'll work.

正试图绑定到 UserControl 的属性 CellNo。添加 RelativeSource 或 ElementName 就可以了。

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

<local:control x:Name="control"  
               CellValue="{Binding Path=CellNo,
                                   ElementName=myWindow,
                                   Mode=TwoWay,
                                   UpdateSourceTrigger=PropertyChanged}">

You may also need to set the the DataContext of control to itself

您可能还需要将控件的 DataContext 设置为自身

public control()
{
    InitializeComponent();
    this.DataContext = this;
    //...
}

Update

更新

You can download a sample application of this here.

您可以在此处下载此示例应用程序。

Otherwise, here's my full sample code.

否则,这是我的完整示例代码。

MainWindow.xaml

主窗口.xaml

<Window x:Class="DependencyPropertyInsideUserControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DependencyPropertyInsideUserControl"
        Title="MainWindow" Height="350" Width="525"
        Name="myWindow">
    <Grid>
        <local:control x:Name="control"
                       CellValue="{Binding Path = CellNo, Mode=TwoWay, ElementName=myWindow, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="Update CellNo" Height="23" HorizontalAlignment="Left" Margin="185,149,0,0" Name="button1" VerticalAlignment="Top" Width="94" Click="button1_Click" />
    </Grid>
</Window>

Mainwindow.xaml.cs

主窗口.xaml.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        CellNo = "Hello";
    }
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        CellNo = "Hi";
    }
    private string m_cellNo;
    public string CellNo
    {
        get
        {
            return m_cellNo;
        }
        set
        {
            m_cellNo = value;
            OnPropertyChanged("CellNo");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

control.xaml

控制文件

<UserControl x:Class="DependencyPropertyInsideUserControl.control"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox Text="{Binding Path = CellValue}" 
                 Name="textBox2" />
    </Grid>
</UserControl>

control.xaml.cs

控件.xaml.cs

public partial class control : UserControl
{
    public string CellValue
    {
        get { return (string)GetValue(CellValueProperty); }
        set { SetValue(CellValueProperty, value); }
    }
    // Using a DependencyProperty as the backing store for LimitValue.  This enables animation, styling, binding, etc...    
    public static readonly DependencyProperty CellValueProperty =
        DependencyProperty.Register("CellValue", typeof(string), typeof(control), new FrameworkPropertyMetadata
        {
            BindsTwoWayByDefault = true,
        });
    public control()
    {
        InitializeComponent();
        this.DataContext = this;
        CellValue = "Test";
    }
}