2013-04-23 151 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