2013-04-23 94 views
1

我创建一个用户控件有一个DependencyProperty但DependencyProperty的是没有得到调用者的传入值。自定义依赖属性不获取绑定输入

我发现在我自己以下调查

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

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

  • 如果当我用的结合提供了依赖属性只看到这个问题,所以这不起作用

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

    ,但我没有问题,如果我摆脱绑定和硬编码的值,所以这个工程

    <common:MyUserControl MyDP="hardCodedValue"/> 
    

这里的背后我的用户代码:

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(); 
    } 
} 

回答

1

这条线在用户控件是错误的:

this.DataContext = this; 

这使得用户控件自己的DataContext的,所以寻找一个叫myvalue的对控件属性的绑定,并且属性不存在。你想让DataContext成为你的视图模型。如果不明确设置它,它将从它的容器(本例中的Window)继承DataContext。

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

+0

删除该行看起来像它帮助!我的MyDPPropertyChanged方法最终被调用,并且具有正确的数据绑定值。谢谢,这让我更接近了。 虽然我仍然有问题 - 用户界面似乎没有得到更新的新值。有任何想法吗?我尝试了AffectsRender = true,但那似乎不起作用。 – 2013-04-23 05:30:33

+0

我也尝试删除回调,因为你建议,并没有区别。 – 2013-04-23 05:38:49

+0

@vivekmaharajh我需要看到一些XAML的UserControl来帮助这方面。 – Jay 2013-04-23 13:15:27

0

请实现INotifyPropertyChanged和PropertyChangedEventHandler在控件以及viewmodel中。其次用SetCurrentValue方法来设置值内部的控制类,而直接将其设置

+0

实现INotifyPropertyChanged没有什么区别 - 请注意,我可以将其视图和视图模型与其他内置控件(如)一起使用,并将我的值传递到其依赖项属性,例如Text = {Binding myValue},所以我很确定视图模型没有问题。 另外,“MyDP”的Setter确实调用了“SetValue”,所以这应该不成问题。 – 2013-04-23 05:34:05

1

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

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

而且在MyDPPropertyChanged方法设置_textBlock的Text属性:

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

这将做到这一点。

+0

谢谢,这确实是“诀窍”。 我希望我能将这个答案和@ Jay的答案都标记为答案,因为他们都解决了我所遇到的不同问题,但是我不会让我这样做,但至少它会让我赞不绝口。 – 2013-04-23 06:34:12

+0

我希望有一个数据绑定的方式来做到这一点虽然... – 2013-04-23 06:44:36

+1

在我的经验中,依赖项属性仅用于调整组件的行为。所有数据绑定都是通过暴露控件视图模型的属性来处理的。 – 2013-04-23 06:56:03