0

我想要一个单例,其中包含一些我可以绑定的值S1S2 。目标是在其值更改时更新一些 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?

4

2 回答 2

1

我认为您没有正确命名您的附加属性的获取/设置访问器,如此处所述。试试这个:

    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}}">
于 2012-04-26T17:54:44.077 回答
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);
        }
   }
于 2012-04-27T08:27:53.420 回答