OnPropertyChanged带字典引用

时间:2017-05-22 10:16:05

标签: c# wpf data-binding

我有像这样的XAML代码

<Grid x:Name="MainGrid">

    <TextBox Text="{Binding A, UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding B, UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding C, Mode=OneWay}" />

</Grid>

和带有DataContext类的C#代码

public class TableData : INotifyPropertyChanging, INotifyPropertyChanged
{

    private Dictionary<string, object> SourceData = new Dictionary<string, object>() { { "A", (double)55 }, { "B", (double)44 } };

    public double A { get { return (double)this["A"]; } set { this["A"] = value; } }
    public double B { get { return (double)this["B"]; } set { this["B"] = value; } }

    public double C { get { return this.A + this.B; } }

    public object this[string key]
    {
        get
        {

            return this.SourceData[key];

        }
        set
        {

            OnPropertyChanging(Binding.IndexerName);

            this.SourceData[key] = value;

            OnPropertyChanged(Binding.IndexerName);

        }
    }

    #region INotify

    protected virtual event PropertyChangedEventHandler PropertyChanged;
    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
        add { PropertyChanged += value; }
        remove { PropertyChanged -= value; }
    }

    protected virtual event PropertyChangingEventHandler PropertyChanging;

    event PropertyChangingEventHandler INotifyPropertyChanging.PropertyChanging
    {
        add { PropertyChanging += value; }
        remove { PropertyChanging -= value; }
    }

    protected virtual void OnPropertyChanged(string Name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(Name));
    }

    protected virtual void OnPropertyChanging(string Name)
    {
        PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(Name));
    }

    #endregion

}

上面的代码可以正常使用DataGrid,但没有使用TextBox。问题是,当我在线更改A或B属性时,C属性不会重新计算。 我不想使用此代码:

  

{Binding [a]}

或像这样的私人财产

  

private double _A {get;组; }

     

私人双A {get {return _A; } set {A = value;   OnPropertyChanged(&#34; A&#34;)}}

因为我有SourceData字典和数据,我从其他代码引用属性A - 警告有效,如果有人键入错误的代码。如果我使用Binding [A],这样做很好,但显然不能正常工作。

有没有办法,重新计算C属性而不使用OnPropertyChanged(&#34; C&#34;)?

2 个答案:

答案 0 :(得分:0)

  

有没有办法,重新计算C属性而不使用OnPropertyChanged(&#34; C&#34;)?

不,没有。至少不是来自视图模型类。 WPF侦听此事件,这意味着每当您想要刷新视图时都必须引发它。

但您可以在OnPropertyChangedA的设置者中调用B方法:

public double A { get { return (double)this["A"]; } set { this["A"] = value; OnPropertyChanged("C"); } }
public double B { get { return (double)this["B"]; } set { this["B"] = value; OnPropertyChanged("C"); } }

答案 1 :(得分:0)

mm8是对的,您必须知道属性的依赖关系,然后才能使用它们:

    private static Dictionary<string, string[]> dependencyDict = new Dictionary<string, string[]>();

static TableData()
{
dependencyDict.Add("A", new string[1]{"C"});
dependencyDict.Add("B", new string[1]{"C"});
}

Dictionary<string, string[]>
    protected virtual void OnPropertyChanged(params string[] propNames)
    {
            if (propNames!=null && PropertyChanged!=null)
            {
                foreach (var propName in propNames)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propName));
                }
            }
    }

    public object this[string key]
    {
        get
        {

            return this.SourceData[key];

        }
        set
        {

            OnPropertyChanging(Binding.IndexerName);

            this.SourceData[key] = value;

            OnPropertyChanged(Binding.IndexerName);
            OnPropertyChanged(dependencyDict[key]);

        }
    }

其他方式是为您的&#34; parent&#34;重置DataContext。 control,包含绑定到计算属性的所有其他控件:Update all bindings in UserControl at once