【问题标题】:OnPropertyChanged with dictionary referenceOnPropertyChanged 与字典参考
【发布时间】:2017-05-22 10:16:05
【问题描述】:

我有这样的 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 属性不会自行重新计算。 我不想使用此代码:

{绑定 [a]}

或像这样的私有财产

私有双 _A { 获取;放; }

私有双 A { 获取 { 返回 _A; } 设置 { A = 值; OnPropertyChanged("A") } }

因为我有包含数据的 SourceData 字典,并且我从其他代码中引用了属性 A - 如果有人键入错误代码,则警告有效。如果我使用 Binding [A],那就可以了,很好,但智能感知不起作用 - 显然。

有什么方法可以在不使用 OnPropertyChanged("C") 的情况下重新计算 C 属性?

【问题讨论】:

标签: c# wpf data-binding


【解决方案1】:

有什么方法可以在不使用 OnPropertyChanged("C") 的情况下重新计算 C 属性?

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

但是你可以在AB的setter中调用OnPropertyChanged方法:

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"); } }

【讨论】:

    【解决方案2】:

    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]);
    
            }
        }
    

    其他方式将为您的“父”控件重置 DataContext,其中包含绑定到计算属性的所有其他控件:Update all bindings in UserControl at once

    【讨论】:

    • 是的,好主意,但想象一下。我有二十多个带有此代码的表,每个表都链接在一起(例如,一个属性引用来自不同类和不同表的另一个属性使用数学​​)。如果我忘记了对财产的一种依赖,那就是大问题。我可以对每个值设置使用 OnPropertyChanged(""),但是这个调用对 wpf 窗口的影响很慢(当然使用大数据和表,我这样做)
    猜你喜欢
    • 2019-07-18
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 2014-07-19
    相关资源
    最近更新 更多