自定义依赖项属性未获取绑定输入

时间:2013-04-23 05:10:00

标签: c# xaml wpf-controls

我正在使用DependencyProperty创建UserControl,但DependencyProperty没有获得调用者传入的值。

我在自己的调查过程中发现了以下内容

  • 如果我使用内置的用户控件,例如TextBlock,一切正常。这将问题缩小到我的UserControl的实现(而不是调用UserControl的代码)

  • 我的属性更改了我注册的回调甚至没有被调用(好吧......至少断点没有被击中)

  • 如果我在使用绑定提供依赖项属性时才看到此问题,那么这不起作用

    <common:MyUserControl MyDP="{Binding MyValue}"/>
    

    但是如果我摆脱绑定并对值进行硬编码,我就没有问题,所以这可行

    <common:MyUserControl MyDP="hardCodedValue"/>
    

这是我的UserControl背后的代码:

public partial class MyUserControl : UserControl
{
    public string MyDP
    {
        get { return (string)GetValue(MyDPProperty); }
        set { SetValue(MyDPProperty, value); }
    }

    public static readonly DependencyProperty MyDPProperty =
        DependencyProperty.Register(
            "MyDP", 
            typeof(string), 
            typeof(MyUserControl),
            new FrameworkPropertyMetadata(
                "this is the default value",
                new PropertyChangedCallback(MyUserControl.MyDPPropertyChanged)));

    public static void MyDPPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        ((MyUserControl)obj).MyDP = (string)e.NewValue;
    }

    public MyUserControl()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

这是xaml

<Grid>
    <TextBlock Text="{Binding MyDP}"/>
</Grid>

由于我可以使用内置的用户控件,例如TextBlock,我不认为错误在于我的主机代码,但在这里,只是为了让你有一个完整的图片:

<StackPanel>
    <common:MyUserControl MyDP="{Binding MyValue}"/>
</StackPanel>

public class MainWindowViewModel
{
    public string MyValue { get { return "this is the real value."; } }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();
    }
}

3 个答案:

答案 0 :(得分:1)

UserControl中的这一行是错误的:

this.DataContext = this;

这使UserControl成为自己的DataContext,因此绑定在UserControl上查找名为MyValue的属性,并且该属性不存在。您希望DataContext成为您的视图模型。如果没有显式设置它,它将从其容器继承DataContext(在本例中为Window)。

删除该行,你会更近。你也不需要那个回调;删除它。

答案 1 :(得分:1)

您可以更新控件的视图代码:

 <Grid>
        <TextBlock x:Name="_textBlock"/>
    </Grid>

在MyDPPropertyChanged方法中设置_textBlock的文本属性:

public static void MyDPPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var control = ((MyUserControl)obj);
        control.MyDP = (string)e.NewValue;
        control._textBlock.Text = control.MyDP;
    }

这样就可以了。

答案 2 :(得分:0)

请在控件侧面和视图模型中实现INotifyPropertyChanged和PropertyChangedEventHandler。其次使用SetCurrentValue方法在控件类中设置值,而不是直接设置它