Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基类不实现INotifyPropertyChange;如何在派生类中实现它?_C#_Wpf - Fatal编程技术网

C# 基类不实现INotifyPropertyChange;如何在派生类中实现它?

C# 基类不实现INotifyPropertyChange;如何在派生类中实现它?,c#,wpf,C#,Wpf,更新: 对不起,我不清楚这个问题。我应该提到: 假设我不能改变基数,并且 基础中有许多属性。示例代码被简化 这里我有一个通过网络反序列化的(基类)对象 public class Base { public string Name { get; set; } } 现在,我希望在WPF应用程序上绑定它的属性,以便在派生类上实现INotifyPropertyChanged public class Derived : Base, INotifyPropertyChanged { priv

更新: 对不起,我不清楚这个问题。我应该提到:

  • 假设我不能改变基数,并且

  • 基础中有许多属性。示例代码被简化


  • 这里我有一个通过网络反序列化的(基类)对象

    public class Base
    {
       public string Name { get; set; }
    }
    
    现在,我希望在WPF应用程序上绑定它的属性,以便在派生类上实现INotifyPropertyChanged

    public class Derived : Base, INotifyPropertyChanged
    {
      private string _derivedName;
    
      public string DerivedName { 
        get { return _derivedName; }
        set
        { 
          _derivedName = value;
          RaisePropertyChanged("DerivedName");
        }
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected virtual void RaisePropertyChanged(string propertyName)
      {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    }
    
    现在我的问题是:当Base.Name更改时,如何引发属性更改事件


    我知道我可以删除继承并重新实现每个基属性并引发事件,但有没有更好的方法?

    更改代码,使基实现接口,并在设置名称时引发事件:

    public class Base : INotifyPropertyChanged
    {
       private string _name;
       public string Name { get
       {
           return _name;
       }
       set{
           if(PropertyChanged != null)
               PropertyChanged(this, new PropertyChangedEventArgs("Some arg"));
           _name = value;
       }
    }
    
       public event PropertyChangedEventHandler PropertyChanged;
    }
    
    “派生”将从基继承接口实现,因此只需将其从类声明中删除:

    public class Derived : Base
    {
      private string _derivedName;
    
      public string DerivedName { 
        get { return _derivedName; }
        set
        { 
          _derivedName = value;
          RaisePropertyChanged("DerivedName");
        }
      }
    
      protected virtual void RaisePropertyChanged(string propertyName)
      {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    }
    

    我将通过包装对基类属性的调用来选择更实用的方法

    public class Derived : Base, INotifyPropertyChanged
    {
    
      public string DerivedName { 
        get { return Name; }
        set
        { 
          Name = value;
          RaisePropertyChanged("DerivedName");
          RaisePropertyChanged("Name"); //probably you will not need this line
        }
      }
    }
    

    创建一个
    新的
    修改器,将基础隐藏到现实世界中,并报告
    名称
    的属性更改,例如:

    public class Derived : Base, INotifyPropertyChanged
    { 
      public new string Name
      {
        get { return base.Name; }
        set { base.Name = value;
              RaisePropertyChanged("Name");
            }
      } 
    }
    
    请参阅MSDN:了解这项工作的原因

    更新 我知道我可以删除继承并重新实现每个基 但有没有更好的办法


    否…如果不进行上述修改,则无法在事后对基类中的setter实现PropertyChange调用。

    除非您可以更改基类。当您引用base.Name时,是否要拦截对该基类属性(Name)的更改或者它只是您想要拦截的许多属性的代表。@DWright谢谢。我应该明确地说我不能修改基础。基础(以及派生的)实现了一个名为IData的接口,该接口包含许多属性(名称只是其中之一)。将更新我的答案。你不能。如果无法修改Base并且无法重写该属性,则无法更改其行为。您所能做的最好的事情是围绕基类创建一个包装类,并针对基类创建代码消耗类。+1,因为我认为这可能是给定约束的最佳选择——但它仍然可能不合适。主要的警告是,对基类的引用调用“Name”将调用
    base.Name
    @McGarnagle想想看。。。即使使用了派生类,当编译器强制执行修饰符时,如何访问基类?记住绑定是使用对象上的反射。如果强制使用新修改器,则无法使用基础。你怎么知道有基类呢?你总是可以将派生的实例强制转换为基类。@McGarnagle当然……但是谁负责为绑定提供实例对象列表呢?是的,这是可能的,但不实用。:-)看见这是危险的;如果有人试图使用基类,它将神奇地停止工作(请注意,使用这种方法与使用我认为被误解的虚拟方法不同)。