【问题标题】:How to update the derived properties using INotifyPropertyChanged如何使用 INotifyPropertyChanged 更新派生属性
【发布时间】:2011-04-25 21:50:31
【问题描述】:

我在 XtratreeList(DevExress) 的 bindingList 中有一些属性,其中子节点需要显示 parentnode'e 属性。我有以下代码。

public abstract class ClassBase : INotifyPropertyChanged
{
    protected static int initialId = 0;

    private int id;
    private int parentID;
    private string productName;
    private string productType;
    private string colorProductType;

    private void RaisePropertyChanged(string propertyName)
    {
        if ( PropertyChanged != null )
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public int ID
    {
        get { return id; }
        set
        {
            if ( id == value )
                return;

            id = value;
            RaisePropertyChanged("ID");
        }
    }

    public int ParentID
    {
        get { return parentID; }
        set
        {
            if ( parentID == value )
                return;

            parentID = value;
            RaisePropertyChanged("ParentID");
        }
    }

    public string ProductName
    {
        get { return productName; }
        set
        {
            if ( productName == value )
                return;

            productName = value;
            RaisePropertyChanged("ProductName");
        }
    }

    public string ProductType
    {
        get { return productType; }
        set
        {
            if ( productType == value )
                return;

            productType = value;
            RaisePropertyChanged("ProductType");
            RaisePropertyChanged("ColorProductType");
        }
    }

    public string ColorProductType
    {
        get { return colorProductType ; }
        set
        {
            if (colorProductType == value)
                return;

            colorProductType = value;
            RaisePropertyChanged("ColorProductType");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}`

我的要求是在ProductType 属性更改时更改ColorProductType 属性,基本上ProductType 是父节点属性,ColorProductType - 子节点属性。所以在改变父母的财产时,孩子的财产也需要改变。我将这两个属性都绑定到 2 个文本框。所以改变父道具应该改变两个文本框,但反之亦然。父级内的RaisePropertyChanged("ColorProductType"); 不起作用,colorproducttype 为空,这是什么问题?

【问题讨论】:

    标签: c# .net binding


    【解决方案1】:

    RaisePropertyChanged 实际上并不更新属性。它只是发出PropertyChanged 事件的信号。某处必须订阅它并相应地更新其他属性。像这样的:

    public abstract class ClassBase : INotifyPropertyChanged
    {
        private string productType;
        private string colorProductType;
    
        public ClassBase()
        {
            this.PropertyChanged += HandlePropertyChanged;
        }
    
        private void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(e.PropertyName == "ProductType")
            {
                // update ColorProductType here
            }
        }
    
        private void RaisePropertyChanged(string propertyName)
        {
            if ( PropertyChanged != null )
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    
        public string ProductType
        {
            get { return productType; }
            set
            {
                if ( productType == value )
                    return;
    
                productType = value;
                RaisePropertyChanged("ProductType");
            }
        }
    
        public string ColorProductType
        {
            get { return colorProductType ; }
            set
            {
                if (colorProductType == value)
                    return;
    
                colorProductType = value;
                RaisePropertyChanged("ColorProductType");
            }
        }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        #endregion
    }
    

    当然,这完全是矫枉过正。当ProductType 更新时,您可以更新ColorProductType,并让PropertyChanged 事件和数据绑定处理文本框更新:

    public string ProductType
    {
        get { return productType; }
        set
        {
            if ( productType == value )
                return;
    
            productType = value;
    
            // update ColorProductType here
    
            RaisePropertyChanged("ProductType");
        }
    }
    

    【讨论】:

    • 感谢您的输入,我可能不得不使用矫枉过正的方法,因为在我的情况下,用户可以编辑 colorproducttype,在这种情况下需要有一个单独的属性来设置 colorprodtype。但是当用户更新产品类型(父母的道具)时,它应该覆盖孩子的属性。您是否建议我保留 colorprodtype 属性并仍然在 Producttype 中更新 colorproducttype?
    • @WittyWoman 是的。我认为我发布的第二个代码示例对您来说应该足够好。我从中省略了ColorProductType,但您应该将其保留在您的实际代码中。然后,当用户更新ColorProductType 时,它将按预期工作,当用户更新ProductType 时,setter 中的代码也将重置ColorProductType。如果您想让事情更加分离,您可以使用我在上面发布的事件处理方法,并避免在您的 ProductType 设置器中更改 ColorProductType 的副作用。
    • 我希望它像更新 colorproducttype 并重新绑定到孩子的文本框一样简单。但是我需要更新孩子的绑定列表,以便在更新父母时看到孩子身上的变化,所以我想我将不得不使用 bindinglist 的 listchanged 事件,找到我正在更改的父级的子级并修改列表中的相应属性。它的手册很漂亮,但我不知道任何其他方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多