views:

65

answers:

2

Hi, I have a viewmodel named EmployeeViewModel which is inherited from ViewModelBase. here is the implementation of ViewModelBase.

    public event PropertyChangedEventHandler PropertyChanged;
    public void FirePropertyChanged(string propertyname)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyname));
    }
    public void FirePropertyChanged<TValue>(Expression<Func<TValue>> propertySelector)
    {
        if (PropertyChanged != null)
        {
            var memberExpression = propertySelector.Body as MemberExpression;
            if (memberExpression != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
            }
        }
    }

My EmployeeViewModel has a property name GridResults, which is bound to the Grid on View, here is the property definition.

    public PagedCollectionView GridResults
    {
        get { return _gridResults; }
        set 
        { 
            _gridResults = value;
            FirePropertyChanged(()=>GridResults); 
        }
    }

Now when i set value of GridResults somewhere in the code in EmployeeViewModel, it fires the property change event and goes into

FirePropertyChanged(Expression> propertySelector)

but inside that method its PropertyChangedEventHandler always remain null and it prevents the complete execution of method. Ultimately my Grid on View remain unnoticed that its underlying itemsource has been changed.

Am i missing something??

Thankx in advance

-K9

A: 

Did your ViewModelBase really implement INotifyPropertyChanged?

if yes, please try the FirePropertyChanged with string parameter.

public PagedCollectionView GridResults
{
    get { return _gridResults; }
    set 
    { 
        _gridResults = value;
        FirePropertyChanged("GridResults"); 
    }
}

btw here is the INPCBase class i use:

/// <summary>
/// Basisklasse für INotifyPropertyChanged.
/// </summary>
public class INPCBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Notify mittels PropertyInfo. HINWEIS: diese Variante ist ungefähr 3x langsamer wie 
    /// <see cref="NotifyPropertyChanged(string)"/> bzw. <see cref="NotifyPropertyChanged(System.ComponentModel.PropertyChangedEventArgs)"/>.
    /// </summary>
    /// <example>
    /// <code>
    /// public string InfoMessage
    /// {
    ///     get {return this.infomessage;}
    ///     set 
    ///     {
    ///         this.infomessage = value;
    ///         this.NotifyPropertyChanged(()=> this.InfoMessage);
    ///     }
    /// }
    /// </code>
    /// </example>
    /// <typeparam name="T"></typeparam>
    /// <param name="property"></param>
    protected void NotifyPropertyChanged<T>(Expression<Func<T>> property)
    {
        var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo;

        if (propertyInfo == null)
        {
            throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
        }

        this.VerifyPropertyName(propertyInfo.Name);

        var handler = PropertyChanged;

        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyInfo.Name));
    }

    /// <summary>
    /// Notify using pre-made PropertyChangedEventArgs
    /// </summary>
    /// <param name="args"></param>
    protected void NotifyPropertyChanged(PropertyChangedEventArgs args)
    {
        this.VerifyPropertyName(args.PropertyName);

        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, args);
        }
    }

    /// <summary>
    /// Notify using String property name
    /// </summary>
    protected void NotifyPropertyChanged(String propertyName)
    {
        this.VerifyPropertyName(propertyName);

        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    #region Debugging Aides

    /// <summary>
    /// Warns the developer if this object does not have
    /// a public property with the specified name. This 
    /// method does not exist in a Release build.
    /// </summary>
    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public void VerifyPropertyName(string propertyName)
    {
        // Verify that the property name matches a real,  
        // public, instance property on this object.
        if (TypeDescriptor.GetProperties(this)[propertyName] != null)
            return;

        var msg = "Invalid property name: " + propertyName;

        if (this.ThrowOnInvalidPropertyName)
            throw new Exception(msg);

        Debug.Fail(msg);
    }

    /// <summary>
    /// Returns whether an exception is thrown, or if a Debug.Fail() is used
    /// when an invalid property name is passed to the VerifyPropertyName method.
    /// The default value is false, but subclasses used by unit tests might 
    /// override this property's getter to return true.
    /// </summary>
    protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

    #endregion // Debugging Aides
}
blindmeis
A: 

Thank you very much for your reply. Yes my ViewModelBase implements the interface, i have also tried that propertychange with String parameter but result is same as PropertyChanged always remain null

Can you please tell me how your class is different in implementing INotifyPropertyChange so that i can try your class or any specific differences.

Thanks,

Ali
hmm just copy and paste my class and try wether it works or not :) i did not see any differences atm. but maybe your "GridResults" are not bind correct? maybe you can post some xaml and more viewmodel code.
blindmeis