【问题标题】:PropertyChange is null when property change by programmatically当以编程方式更改属性时,PropertyChange 为空
【发布时间】:2019-09-20 14:43:19
【问题描述】:

我在 DataGrid 中有一个复选框列,在 DataGrid 列中有一个主复选框。当我选中主复选框时,DataGrid 中所有选中的复选框都将被选中。

当我选中主复选框时,我会检查所有类似的布尔属性 =>

foreach (TSModel value in TimeSheetList.Intersect(selectedlist))
            {

                if (!chkmain.IsChecked.GetValueOrDefault())
                {
                    value.IsApproved = false;                     
                }
                else
                {
                    value.IsApproved = true;                      
                }
            }

我的 TSModel =>

public class TSModel:BaseModel, ICloneable
{

    bool _IsApproved;
    public bool IsApproved
    {
        get
        {
            return _IsApproved;
        }
        set
        {               

            if (_IsApproved != value)
            {
                _IsApproved = value;
                RaisePropertyChange("IsApproved");                   
            }
        }
    }

 }

我的基础模型 =>

public class BaseModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChange(string prop)
    {
        try
        {               
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
                IsUpdated = true;
            }                
        }
        catch (Exception ex)
        {
            throw ex;
        }            
    }
    bool _IsUpdated = false;
    public virtual bool IsUpdated
    {
        get
        {
            return _IsUpdated;
        }
        set
        {
            _IsUpdated = value;
        }
    }
}

我的问题是,如果我检查个人,This propertychanged 不为 null 并且 IsUpdated 属性为 true,但是如果我通过 Main 复选框检查并通过 Code 检查更改,则 This propertychanged 为 null 而 IsUpdated 为 false。

当我通过代码检查时,为什么我的 propertychanged 为空?

更新

  • 我看到另一个不知道原因,我有100行,我只能看到15条记录,其余的都是垂直滚动显示的。因此,当我检查更改所有复选框时,但如果我只看到 1 到 15,则只有 1 到 15 的属性更改值具有值,其余为空。如果我看到 85 到 100,只有 85 到 100 和 1 到 15 的属性更改值具有值其余为空。

【问题讨论】:

  • 嗨,有人请编辑我的代码格式问题。我不知道为什么我不能将我的代码更改为代码格式。正文部分没有选项。
  • 不是一个答案,只是一个提示,但是当调用RaisePropertyChange 传递nameof(...) 而不是"..." 时,这将防止您被错字或如果您要更改属性而绊倒名称等...
  • 这个问题似乎与this重复

标签: c# wpf inotifypropertychanged


【解决方案1】:

这是意料之中的,因为您当前看不到的项目(即 16 到 100 之间的行)是虚拟化的。无需为这些引发 PropertyChanged 事件,因为它们无论如何都不会在屏幕上可见。

尽管如此,您仍应设置这些对象的属性值,但您不必担心不会引发 PropertyChanged 事件。基类的 RaisePropertyChange 方法除了引发事件之外不应做任何其他事情:

public class BaseModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChange(string prop)
    {
        try
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    bool _IsUpdated = false;
    public virtual bool IsUpdated
    {
        get
        {
            return _IsUpdated;
        }
        set
        {
            _IsUpdated = value;
            RaisePropertyChange("IsUpdated");
        }
    }
}

你应该在IsApproved的setter中设置IsUpdated属性:

public bool IsApproved
{
    get
    {
        return _IsApproved;
    }
    set
    {

        if (_IsApproved != value)
        {
            _IsApproved = value;
            RaisePropertyChange("IsApproved");
            IsUpdated = true;
    }
}

另一个选项是在null 检查之前设置属性:

public void RaisePropertyChange(string prop)
{
    try
    {          
        IsUpdated = true;     
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }                
    }
    catch (Exception ex)
    {
        throw ex;
    }            
}

如果您正确绑定了CheckBox,它将在它变得可见时(即当您将其滚动到视图中时)根据源属性被选中或取消选中。

您可以在docs 中阅读有关 UI 虚拟化概念的更多信息。

【讨论】:

  • 谢谢,它看起来就像我现在所面临的。但是用户在选中主复选框后不会向下滚动,我该怎么做?
  • @Arkar:你怎么能做什么?对于虚拟化项目,您无需担心 PropertyChanged 事件为空。不可见的项目没有订阅者。
  • 即使项目不可见,也应该更改属性。我的要求就是这样,现在我通过匹配两个列表来临时修复,但我知道这对性能不利。
  • 我不知道如何解决这个问题,而 StackOverflow 是我唯一可以寻求帮助的人。谢谢。
  • 您不应该在RaisePropertyChange 方法中设置IsUpdated 属性。查看我的编辑。
猜你喜欢
  • 1970-01-01
  • 2017-02-27
  • 2021-09-03
  • 2016-05-22
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多