1

XAML {Binding} 构造非常方便,因为它会自动处理所有 PropertyChanged 问题。当您通过 .NET 数据结构将路径传递给对象时,这确实令人印象深刻,并且所有内容都会为您自动更新。

我想在 C# 中使用同样的东西。我想要一个从另一个属性的值派生的属性。例子

class Foo
{
    public Bar Bar = new Bar();
    public string ItGetter
    {
        get
        {
            return Bar.Baz.It;
        }
    }
}

class Bar
{
    public Baz Baz = new Baz();
}

class Baz
{
    public string It { get { return "You got It!"; } }
}

如果您在 Foo 上调用 ItGetter,您会从 Baz 获得 It 值。这工作正常,除了它没有失效——即,如果它改变了,ItGetter 上就没有改变通知。此外,如果 Foo.Bar 或 Bar.Baz 引用发生更改,您也不会收到更改通知。

我可以在属性上添加适当的 IChangeNotify 代码,但我的问题是:如何对 ItGetter 属性进行编码,以便在路径中的任何引用或 It 值更改时调用其 PropertyChanged 事件?我希望我不必在路径中的所有项目上手动设置属性更改事件....

谢谢你的帮助!

埃里克

4

2 回答 2

1

你可以看看依赖属性。它们允许您在 WPF 属性系统中定义由元数据堆栈和详细的值解析系统支持的属性。

对您来说重要的是,它们允许您注册属性更改事件,并且它们允许您使值依赖于其他东西。

还有一些其他很好的文章,例如Josh Smith 的“Demystifying dependency properties”Christian Mosers 的“Dependency Properties”

您可能还想阅读依赖属性回调和验证

于 2010-04-27T21:32:04.153 回答
1

正如西蒙提到的,这是使用依赖属性完成我正在寻找的完整代码:

// This class exists to encapsulate the INotifyPropertyChanged requirements
public class ChangeNotifyBase : DependencyObject, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

public class Foo : ChangeNotifyBase
{
    public Foo()
    {
        Bar = new Bar();
        var binding = new Binding("Bar.Baz.It");
        binding.Source = this;
        binding.Mode = BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ItGetterProperty, binding);
    }

    /// <summary>
    /// The ItGetter dependency property.
    /// </summary>
    public bool ItGetter
    {
        get { return (bool)GetValue(ItGetterProperty); }
        set { SetValue(ItGetterProperty, value); }
    }
    public static readonly DependencyProperty ItGetterProperty =
        DependencyProperty.Register("ItGetter", typeof(bool), typeof(Foo));

    // Must do the OnPropertyChanged to notify the dependency machinery of changes.
    private Bar _bar;
    public Bar Bar { get { return _bar; } set { _bar = value; OnPropertyChanged("Bar"); } }
}

public class Bar : ChangeNotifyBase
{
    public Bar()
    {
        Baz = new Baz();
    }
    private Baz _baz;
    public Baz Baz { get { return _baz; } set { _baz = value; OnPropertyChanged("Baz"); } }
}

public class Baz : ChangeNotifyBase
{
    private bool _it;
    public bool It { get { return _it; } set { _it = value; OnPropertyChanged("It"); } }
}

如果您现在在 ItGetter 上注册事件,如果这些事情发生任何变化,您将收到通知:Baz.It Foo.Bar(即,更改参考)Bar.Baz " "

如果将对象引用(Foo.Bar 或 Bar.Baz)中的一个设置为 null,则 ItGetter 的值将更改为 false。

于 2010-04-29T16:32:24.223 回答