我希望有一个包含我可以绑定的值 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?
答案 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);
}
}