KyloRen
KyloRen

Reputation: 2741

How to get Type from PropertyChanged event?

I will explain what I am trying to do first.

I have a quite a few of DataGrids and each DataGrid use different classes for there data type and instead of subscribing an Event handler for each one, I was hoping to make a generic event handler and get the type from from the sender object.

I am using EntityFramework Database First

One example of one of the classes:

public partial class StaffData : INotifyPropertyChanged
{
    public long ID { get; set; }        
    public string StaffNameFirst { get; set; }
    public string StaffNameSecond { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }       
}

My ViewModel:

VeiwModelBase holds the INotifyPropertyChanged data.

public class MasterViewModel : ViewModelBase
{
    public static ObservableCollection<StaffData> MasterDataBinding
    {
        get { return _mMasterData; }
        private set
        {
            if (value == _mMasterData)
                return;

            _mMasterData = value;
            OnPropertyChanged();
        }
    }

    public MasterViewModel()
    {
        _mMasterData.CollectionChanged += master_CollectionChanged;
    }


    public void master_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        //asign PropertyChanged event here 
    }

    private void master_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Type foo = sender.GetType().GetGenericArguments()[0];
        var newRowData = sender as foo;                    
        SaveData(newRowData);
    }

    private static void SaveData(object newRowData)
    {      
        Type foo = newRowData.GetType().GetGenericArguments()[0];
        var originalData = dataBaseEntities.foo.FirstOrDefault(p => p.ID == newRowData.ID);
        entities.Entry(originalData).CurrentValues.SetValues(newRowData);
        dataBaseEntities.SaveChanges();        
    }
}

These are the two methods above which I can't seem to figure this out, I have tried countless ways using Getype with not much success (I left my last attempt in hopefully to illustrate what I am trying to do). I have commented out how I am normally going about this:

private void master_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    Type foo = sender.GetType().GetGenericArguments()[0];
    var newRowData = sender as foo; 
    //var newRowData = sender as StaffData             
    SaveData(newRowData);
}

//private static void SaveData(StaffData newRowData)
private static void SaveData(object newRowData)
{      
    Type foo = newRowData.GetType().GetGenericArguments()[0];
    var originalData = dataBaseEntities.foo.FirstOrDefault(p => p.ID == newRowData.ID);
    //var originalData = dataBaseEntities.StaffData.FirstOrDefault(p => p.ID == newRowData.ID);
    entities.Entry(originalData).CurrentValues.SetValues(newRowData);
    entities.SaveChanges();        
}

When trying to use the variable as a type I get this error,

Error CS0118 'foo' is a variable but is used like a type

Is there a way to get the type when you don't know which datagrid will implement the PropertyChanged event and use it so as you can make a generic event handler for all the Datagrid controls?

Or am I going about this the wrong way?

Upvotes: 1

Views: 1407

Answers (2)

Omri Aviv
Omri Aviv

Reputation: 126

You cant get the type inside the propertyChanged event handler but you can get the property name from PropertyChangedEventArgs. Something like:

private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            if (args.PropertyName == "SomePropertyName")
            {
                //... do your stuf
            }
        }

Upvotes: 0

Clemens
Clemens

Reputation: 128097

Not sure if I really understand your question, but you could check the type of the sender argument at runtime and call an appropriate method like this:

private void master_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (sender is StaffData)
    {
        DoSomething((StaffData)sender);
    }
    else if (sender is SomeOtherData)
    {
        DoSomething((SomeOtherData)sender);
    }
    ...
}

private void DoSomething(StaffData data)
{
    ...
}

private void DoSomething(SomeOtherData data)
{
    ...
}

However, I'd prefer to have different PropertyChanged handler methods for different sender types.

Upvotes: 1

Related Questions