2010-07-16 62 views
10

我有一個用戶控件,我想參與數據綁定。我已經在用戶控件中設置了依賴項屬性,但無法使其工作。數據綁定到WPF中的UserControl

當我用靜態文本(例如BlueText =「ABC」)調用它時,uc顯示正確的文本。當我嘗試將其綁定到本地公共屬性時,它始終爲空。

<src:BlueTextBox BlueText="Feeling blue" />   <!--OK--> 
<src:BlueTextBox BlueText="{Binding Path=MyString}" /> <!--UserControl always BLANK!--> 
<TextBox Text="{Binding Path=MyString}" Width="100"/> <!--Simple TextBox Binds OK--> 

我已經將代碼煮成下面的簡化示例。下面是用戶控件的XAML:

<UserControl x:Class="Binding2.BlueTextBox" ... 
    <Grid> 
     <TextBox x:Name="myTextBox" Text="{Binding BlueText}" Foreground="Blue" Width="100" Height="26" /> 
    </Grid> 

這裏是用戶控件的代碼後面:

public partial class BlueTextBox : UserControl 
{ 
    public BlueTextBox() 
    { 
     InitializeComponent(); 
     DataContext = this; // shouldn't do this - see solution 
    } 

    public static readonly DependencyProperty BlueTextProperty = 
     DependencyProperty.Register("BlueText", typeof(string), typeof(BlueTextBox)); 

    public string BlueText 
    { 
     get { return GetValue(BlueTextProperty).ToString(); } 
     set { SetValue(BlueTextProperty, value.ToString()); } 
    } 

這似乎是它應該是很容易的,但我不能使它發揮作用。謝謝你的幫助!

更多信息:當我嘗試修復尤金建議的修復時,我注意到一些奇怪的行爲。我爲元數據添加了一個PropertyChangedCallback;這讓我可以看到BlueText的價值。當將字符串設置爲靜態值(=「感覺藍色」)時,PropertyChanged事件觸發。數據綁定的情況下不會觸發PropertyChanged。我認爲這意味着數據綁定值不會發送到UserControl。 (我認爲構造函數在靜態情況下不會被調用)

解決方案:問題被Arcturus和jpsstavares正確識別。首先,當在控件的構造函數中設置DataContext = this時,我覆蓋了數據綁定。這阻止了數據綁定值的設置。我還必須命名控件x:Name = root,並指定Binding ElementName = root int XAML。爲了獲得TwoWay綁定,我需要在調用者中設置Mode = TwoWay。下面是正確的代碼:

<src:BlueTextBox BlueText="{Binding Path=MyString, Mode=TwoWay}}" /> <!--OK--> 

現在XAML的用戶控件:

<UserControl x:Class="Binding2.BlueTextBox" x:Name="root"... 
    <Grid> 
     <TextBox x:Name="myTextBox" Text="{Binding ElementName=root, Path=BlueText}" Foreground="Blue" Width="100" Height="26" /> 
    </Grid> 

最後我刪除了的DataContext =這在用戶控件的構造函數。

public BlueTextBox() 
    { 
     InitializeComponent(); 
     //DataContext = this; -- don't do this 
    } 

感謝大家的巨大幫助!

回答

11

您設置的DataContext在控制自身,從而使用於其他控制這種控制時覆蓋的DataContext。以你的例子在您的具體情況結合:

<src:BlueTextBox BlueText="{Binding Path=MyString}" /> 

一旦加載所有的DataContext設置,它會尋找你的BlueTextBox事情控制路徑的MyString由於你在DataContext設置它。我想這不是你打算如何工作;)。

解決方案:

更改文本結合要麼2個綁定之一:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:BlueTextBox}}, Path=BlueText} 

名稱控件的根(或類似的東西)

<UserControl x:Name="Root" 

{Binding ElementName=Root, Path=BlueText} 

並刪除

DataContext = this; 

從您的用戶控件的構造函數,它應該工作就像一個魅力..

0

可能需要將您的屬性FrameworkPropertyMetadata添加到指定FrameworkPropertyMetadataOptions.AffectsRender和AffectsMeasure的位置。

FrameworkPropertyMetadataOptions enumeration MSDN article

+0

嘗試設置兩個AffectsRender和AffectsMeasure期間,但是這並沒有任何影響。謝謝。 – RaoulRubin 2010-07-16 14:37:48

2

我認爲在這種情況下,你需要設置ElementName屬性的綁定。事情是這樣的:

<UserControl x:Class="Binding2.BlueTextBox" x:Name="blueTextBox"... 
<Grid> 
    <TextBox x:Name="myTextBox" Text="{Binding ElementName=blueTextBox, Path=BlueText}" Foreground="Blue" Width="100" Height="26" /> 
</Grid> 
0

我知道這是一個老話題,但仍。

還提到了在UIPropertyMetadata的PropertyChangedCallback註冊您的DP