如何将`DependenyProperty`绑定到另一个可附加的`DependencyProperty`?

时间:2012-04-26 16:26:53

标签: wpf binding

我希望有一个包含我可以绑定的值 S1 S2 的值的单例。目标是在其值发生变化时更新一些UIElements。问题是我想使用重用DataTemplate内的值。这意味着我无法直接绑定到单例的依赖属性,但必须将其设置在外部。

要正确传递更新,值必须为DependencyProperty。因为我不知道我必须绑定哪个属性,所以创建了与值相同类型的另一个可附加属性 AttProperty 。现在我尝试将 S1 绑定到 AttProperty ,但这给了我一个错误:

  

附加信息:无法设置'绑定'   'TextBox'类型的'SetAttProperty'属性。 '绑定'只能是   在DependencyObject的DependencyProperty上设置。

那么如何将可附着的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?

2 个答案:

答案 0 :(得分:1)

我认为您没有按照文档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}}">

答案 1 :(得分: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);
        }
   }