2012-04-26 50 views
0

我想擁有一個持有一些值的單身人士S1S2我可以綁定到。目標是在其值更改時更新一些UIElements。問題是我想使用重用的DataTemplate中的值。這意味着我不能直接綁定到單例的依賴屬性,但必須在外部設置。如何將一個`DependenyProperty`綁定到另一個可附加的`DependencyProperty`?

要正確傳遞更新,值必須是DependencyProperty。因爲我不知道我必須綁定哪個屬性,所以我創建了另一個與數值相同類型的可附加屬性AttProperty。現在,我試圖綁定S1AttProperty但是這給了我一個錯誤:

Additional information: A 'Binding' cannot be set on the 'SetAttProperty' property of type 'TextBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

那麼,如何可以綁定可連接DependencyProperty另一個DependencyProperty

下面是單身我到目前爲止(C#)代碼:

public class DO : DependencyObject 
{ 
    // Singleton pattern (Expose a single shared instance, prevent creating additional instances) 
    public static readonly DO Instance = new DO(); 
    private DO() { } 
    public static readonly DependencyProperty S1Property = DependencyProperty.Register(
    "S1", typeof(string), typeof(DO), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)); 
    public string S1 
    { 
    get { return (string)GetValue(S1Property); } 
    set { SetValue(S1Property, value); } 
    } 
    public static readonly DependencyProperty AttProperty = DependencyProperty.RegisterAttached( 
    "Att", typeof(string), typeof(DO), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)); 
    public static void SetAttProperty(DependencyObject depObj, string value) 
    { 
    depObj.SetValue(AttProperty, value); 
    } 
    public static string GetAttProperty(DependencyObject depObj) 
    { 
    return (string)depObj.GetValue(AttProperty); 
    } 
} 

這裏是有問題的東西(XAML):

<TextBox Name="Input" Text="" TextChanged="Input_TextChanged" local:DO.AttProperty="{Binding Source={x:Static local:DO.Instance}, Path=S1}" /> 

更新

隨着博金利的變化錯誤消失了。但是,一個問題仍然是 - 如果我現在嘗試用這樣的附加屬性的幫助來更新單:

<TextBox local:DO.Att="{Binding Source={x:Static local:DO.Instance}, Path=S1, Mode=TwoWay}" Text="{Binding Path=(local:DO.Att), RelativeSource={RelativeSource Self}, Mode=TwoWay}"/> 

爲什麼不值在單傳播到S1?

回答

1

您需要執行INotifyPropertyChanged和電線的變化到依賴屬性變化。

public class DO : DependencyObject,INotifyPropertyChanged { 
     // Singleton pattern (Expose a single shared instance, prevent creating additional instances) 
     public static readonly DO Instance = new DO(); 
     private DO() { } 
     public static readonly DependencyProperty S1Property = DependencyProperty.Register(
      "S1", typeof(string), typeof(DO), 
      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender,onS1Changed)); 

     private static void onS1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
      DO item = d as DO; 
      if (item != null) item.OnPropertyChanged(new PropertyChangedEventArgs("S1")); 
     } 

     public string S1 { 
      get { return (string)GetValue(S1Property); } 
      set { SetValue(S1Property, value); } 
     } 
     public static readonly DependencyProperty AttProperty = DependencyProperty.RegisterAttached(
      "Att", typeof(string), typeof(DO), 
      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender,onAttChanged)); 

     private static void onAttChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
      DO item = d as DO; 
      if (item != null) item.OnPropertyChanged(new PropertyChangedEventArgs("Att")); 
     } 

     public static void SetAttProperty(DependencyObject depObj, string value) { 
      depObj.SetValue(AttProperty, value); 
     } 
     public static string GetAttProperty(DependencyObject depObj) { 
      return (string)depObj.GetValue(AttProperty); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public void OnPropertyChanged(PropertyChangedEventArgs e) { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) handler(this, e); 
     } 
    } 
+0

這仍然不會更新單身的情況下,在文本框中的值更改。如果我正確理解這一點,Att不會改變,但它包含的屬性S1。如果我想用綁定重新設置Att,則會觸發一個事件。或者我對更新機制有錯誤的理解? – Pascal 2012-04-27 09:28:11

+0

在建議的代碼中,'onAttChanged'希望'DependencyObject'成爲'DO'。但是'Att'沒有設置在單例'DO'上,而是連接到其他元素 - 在這個例子中是一個TextBox。所以我想這永遠不會成功。 – Pascal 2012-04-27 11:06:25

+0

在這種情況下,應該無關緊要,因爲依賴項更新應該觸發。當你說S1沒有改變時,你如何檢查。您是否期望更新爲文本更改(即用戶輸入)或失去焦點(這是默認設置) – 2012-04-27 11:12:00

1

我不認爲您正確指定了您的附加屬性的Get/Set訪問器,如記錄here。試試這個:

public static readonly DependencyProperty AttProperty = DependencyProperty.RegisterAttached(
     "Att", typeof(string), typeof(DO), 
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)); 
    public static void SetAtt(DependencyObject depObj, string value) 
    { 
     depObj.SetValue(AttProperty, value); 
    } 
    public static string GetAtt(DependencyObject depObj) 
    { 
     return (string)depObj.GetValue(AttProperty); 
    } 

實例綁定:

<TextBlock local:DO.Att="{Binding Source={x:Static local:DO.Instance}, Path=S1}" Text="{Binding Path=(local:DO.Att),RelativeSource={RelativeSource Self}}"> 
+0

謝謝博金利 - 值現在正確顯示。如果我使用相同的綁定來修改它們不被更新的值。我更新了這個問題來反映這一點。任何想法爲什麼綁定不更新單身人士? – Pascal 2012-04-27 08:17:30

+0

+1讓我去... – Pascal 2012-04-27 10:50:47

相關問題