我有一个简单的依赖属性。我有一个带按钮的用户控件。我希望调用者将名为MyName的属性设置为“Hello”。我希望依赖属性代码将字符串“World”追加到末尾。这是我的代码尝试这个:
#region MyNAME DEPENDENCY PROPERTY
private string _myName;
public string MyName
{
get { return this._myName; } //a breakpoint here never trips
set
{
this._myName = value;
this.OnPropertyChanged("MyName");
}
}
public string MyName2 { get { return this._myName; } } //a breakpoint here will trip
public static readonly DependencyProperty MyNameProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl), new PropertyMetadata("", OnMyNamePropertyChanged));
private static void OnMyNamePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
MyTabControl myUserControl = dependencyObject as MyTabControl;
myUserControl.OnMyNamePropertyChanged(e);
myUserControl.OnPropertyChanged("MyName");
}
private void OnMyNamePropertyChanged(DependencyPropertyChangedEventArgs e)
{
this.MyName = (string)e.NewValue + " World";
}
#endregion //end MyNAME
我的按钮XAML代码如下:
<Button Content="{Binding Path=MyName, Mode=OneWay}" />
当我加载具有此控件的页面时:
<local:MyTabControl MyName="Hello" />
我得到一个显示“Hello”的按钮,而不是一个显示“Hello World”的按钮。奇怪的是,如果我将我的按钮XAML代码更改为使用MyName2,如下所示:
<Button Content="{Binding Path=MyName2, Mode=OneWay}" />
它有效。 getter代码是相同的(我在上面包含它)。我猜测得到_myName的代码比我预期的更早被调用。我也没想到的是MyName getter似乎永远不会被调用。当我在那里设置断点时,它不会跳闸。当我更改按钮绑定路径以使用MyName2时,放置在该getter上的断点将跳闸。
我在这里做错了什么?如何使用MyName属性并让我的按钮显示“Hello World”(当然不使用第二个getter)
编辑:添加新代码。
我接受了你的两条建议并将我的C#代码更改为:
public string MyName
{
get { return (string)GetValue(MyNameCustomProperty); }
set { SetValue(MyNameCustomProperty, value + " World"); }
}
public static DependencyProperty MyNameCustomProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl));
(我还不熟悉依赖属性)我仍然遇到与之前代码相同的问题。我可以用这段代码做点什么吗?
答案 0 :(得分:1)
这里的部分问题是你没有使用真正的依赖属性。要使用依赖项属性,您需要使用实际的依赖项属性存储而不是字段。这种后备存储是绑定等项目的值。将您的代码更改为以下内容并删除支持字段
public string MyName
{
get { return (string)this.GetValue(MyNameProperty); }
set { this.SetValue(MyNameProperty, value); }
}
答案 1 :(得分:1)
看起来我需要强迫价值。我是这样做的:
public string MyName
{
get { return (string)GetValue(MyNameCustomProperty); }
set { SetValue(MyNameCustomProperty, value); }
}
public static DependencyProperty MyNameCustomProperty = DependencyProperty.Register("MyName", typeof(string), typeof(MyTabControl), new PropertyMetadata("", MyPropertyChanged, CoerceCurrentReading));
private static void MyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//contains coerced value
}
private static object CoerceCurrentReading(DependencyObject d, object value)
{
MyTabControl tab = (MyTabControl)d;
return (string)value + " World";
}
这看起来是将XAML代码输入的值从“Hello”更改为“Hello World”的最简洁方法。
答案 2 :(得分:0)
您希望更改通知发生前设置的值。最简单的解决方案是将支持字段的值设置为您想要的值,然后通知:
public string MyName
{
get { return this._myName; } //a breakpoint here never trips
set
{
this._myName = (string)value + "World!";
this.OnPropertyChanged("MyName");
}
}
您遇到的问题是您设置了支持字段。 然后通知,告诉UI更新,以及触发OnNotifyPropertyChanged。 在属性更改后调用OnNotifyPropertyChanged,您尝试更改后备字段。