简体   繁体   中英

PropertyChangedEventHandler How to get value?

So I've setup the event to a class

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    }

And it's fired when a class's property gets changed, however I want to make the same change in a similar class. Take this as an example

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

and the event binding for class A;

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    }

what I want is to copy the content of the Name property of A and assign it to an instance of B.

What is the elegant way to do that? My problem is knowing which value of A has changed(in my class it's not only name, but more).

Use the PropertyName attribute of the PropertyChangeEventArgs to figure out which property was modified, then use some logic to set that property to, what I'm calling, the boundItems .

You can use the sender object and cast it to the appropriate type if you need to as well, this allows for a bit more flexibility. Using Reflection will allow you to get and set the property with no real manual labor involved by just using the String value of the PropertyName , but it's much more overhead, so if you're doing this a lot, I'd advise against it.

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

Alternatively, you can use Reflection to set the property instead of building a switch case.

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

You best option, though, is to create the classes with these ties built into the object's properties. Modify the get and set of the properties to set both the affected property and the boundItems property as well. That would look like this:

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

You have to use Reflection and sample code will look like this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM