PropertyChangedEventHandler 如何获取值?

8
所以我已经将事件设置为一个类。
    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    }

当一个类的属性被更改时,它会触发这个事件,但我想在另一个类中做出相同的更改。拿这个例子来说。

class A: INotifyPropertyChanged
{
   //event handler declaration

   string PhoneNumber;

   string _name;
   Public string Name {
     get { return _name;}
     set { _name = value; PropertyChanged("Name");}
   }
}

class B
{
   string Name;
   int age;
}

以及A类的事件绑定;

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    }

我想要的是将A对象的Name属性内容复制并赋值给B对象实例。

有哪些简洁的方法可以实现这个目标?我的问题是如何知道A对象的哪个值发生了变化(在我的类中不仅仅是名称,还有其他属性)。

2个回答

11

使用 PropertyChangeEventArgs 的 PropertyName 属性 来确定哪个属性被修改,然后使用一些逻辑将该属性设置为我称之为“boundItems”的内容。

如果需要的话,您可以使用发送者对象并将其强制转换为适当的类型,这样可以更灵活。使用 Reflection 将允许您仅通过使用 PropertyNameString 值来获取和设置属性,而无需进行实际手动工作,但它是更多开销,所以如果您经常这样做,我建议不要使用它。

void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch(e.PropertyName)
    {
        case "Name":
            //You Code
            boundItem.Name = (sender as A).Name;
            break;
    } 
}

或者,您可以使用反射来设置属性,而不是构建一个开关语句。

void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    //Untested Reflection example. Probably needs some modifying. 
    PropertyInfo prop = typeof(A).GetType()
              .GetProperty(e.PropertyName, BindingFlags.Public | BindingFlags.Instance);
    PropertyInfo boundProp = typeof(B).GetType()
              .GetProperty(e.PropertyName, BindingFlags.Public | BindingFlags.Instance);
    boundProp.SetValue (boundItem, prop.GetValue((sender as A),0), null);
}

然而,最佳的选择是在对象属性中嵌入这些关联,并修改属性的 getset 方法以设置受影响的属性和 boundItems 属性。代码示例如下:

class A: INotifyPropertyChanged
{
   string PhoneNumber;
   string _name;
   B BoundItem = null;
   Public string Name {
     get { return _name;}
     set 
     { 
         _name = value; 
         if(BoundItem != null)
              BoundItem.Name = value;
     }
}

class B
{
   string Name;
   int age;
}

class Main
{
     public Main()
     {
         A item = new A();
         B boundItem = new B();
         item.BoundItem = boundItem;
         item.Name = "TEST";
         Console.WriteLine("Item Name: " + item.Name);
         Console.WriteLine("BoundItem Name: " + boundItem.Name);

         // Result:
         // Item Name: TEST
         // BoundItem Name: TEST
     }
}

那么你可以在switch case中写"bounditem.Name = (sender as B).Name"。或者,你可以使用反射来实现,但它的效率要低得多,但更加灵活。 - corylulu
编辑了我的答案,为您提供了如何使用反射方法作为替代方案的大致示例。不过,您也可以将自定义方法直接构建到类本身中。因此,可以覆盖类属性以设置两个值,而无需依赖于PropertyChange事件。 - corylulu

0

你需要使用反射,示例代码如下:

public class SomeClass : INotifyPropertyChanged
{

    public void OnPropertyChanged(string propertyName , object before, object after)
    {
        Type type = this.GetType();
        var val = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(this, null); //Contains changed value 
        if (propertyName == "Name) {
           //Do whatever you want to do with value for "Name"
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接