C# 如何修改依赖项属性的setter值?

C# 如何修改依赖项属性的setter值?,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我有一个简单的依赖属性。我有一个带按钮的用户控件。我希望调用方将名为MyName的属性设置为“Hello”。我希望依赖项属性代码在末尾附加字符串“World”。以下是我尝试此操作的代码: #region MyNAME DEPENDENCY PROPERTY private string _myName; public string MyName { get { return this._myName; } //a breakpoint here never trips set

我有一个简单的依赖属性。我有一个带按钮的用户控件。我希望调用方将名为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}" />

(我对Dependency属性仍然是新手)我仍然存在与以前代码相同的问题。我可以用这段代码做些什么吗?

这里的部分问题是您没有使用真正的依赖属性。要使用依赖项属性,您需要使用实际的依赖项属性存储,而不是字段。这种后备存储是绑定之类的项获取其值的地方。将代码更改为以下内容并删除支持字段

public string MyName
{
    get { return (string)this.GetValue(MyNameProperty); }
    set { this.SetValue(MyNameProperty, value); }
}

看起来我需要强制执行该值。我是这样做的:

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”的最干净的方法。

您希望在通知发生之前更改设置的值。最简单的解决方案是将backing字段的值设置为所需值,然后通知:

public string MyName
{
    get { return this._myName; } //a breakpoint here never trips
    set
    {
        this._myName = (string)value + "World!";
        this.OnPropertyChanged("MyName");
    }
}
您遇到的问题是设置了支持字段。 然后通知,通知用户界面进行更新,并触发OnNotifyPropertyChanged。
OnNotifyPropertyChanged在属性更改后调用,您可以尝试更改支持字段。

我尝试使用此代码,但仍然存在相同的问题。你可以在我原来的帖子底部看到我的代码。我将“World”附加到setter中的值,但按钮仍然只显示“Hello”。我是不是把代码粘贴错了?我想你有一个自定义的OnPropertyChanged函数?默认值不采用
string
它采用
PropertyChangedEventArgs
MyClass
MyTabControl
实现
INotifyPropertyChanged
。我有一个简单的
OnPropertyChanged
事件处理程序,它调用
this.PropertyChanged(…)
。我拿一根绳子。我看到我在粘贴的代码中遗漏了这一点。这对我来说不起作用。这与我的第一次尝试相似。看看这行
this.MyName=(string)e.NewValue+“World”OnMyNamePropertyChanged
中的code>。它附加“世界”字符串。这就是您所建议的,只是它发生在调用堆栈的前面一步。
public string MyName
{
    get { return (string)this.GetValue(MyNameProperty); }
    set { this.SetValue(MyNameProperty, value); }
}
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";
}
public string MyName
{
    get { return this._myName; } //a breakpoint here never trips
    set
    {
        this._myName = (string)value + "World!";
        this.OnPropertyChanged("MyName");
    }
}