以编程方式更改属性时,PropertyChange为null

时间:2019-05-02 05:48:27

标签: c# wpf inotifypropertychanged

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

 }

我的BaseModel =>

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

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

为什么通过代码检查时我的propertychanged为null?

更新

  • 我看到另一个不知道原因,我有100行,我只能看到15条记录,其余的都通过垂直滚动显示。因此,当我选中全部更改复选框时,如果我只看到1到15,则此1到15的只有属性更改的值才有值,其余值为null。如果我将视线更改为85到100,则只有85到100和1到15的属性更改值才有值其余均为空。

1 个答案:

答案 0 :(得分: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");
        }
    }
}

您应该在IsUpdated的设置器中设置IsApproved属性:

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虚拟化概念的更多信息。