PropertyChangedEventHandler имеет значение null в FirePropertyChanged.

У меня есть модель представления с именем EmployeeViewModel, которая унаследована от ViewModelBase. вот реализация 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));
            }
        }
    }

Моя модель EmployeeViewModel имеет имя свойства GridResults, которое привязано к сетке в представлении, вот определение свойства.

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

Теперь, когда я устанавливаю значение GridResults где-то в коде в EmployeeViewModel, он запускает событие изменения свойства и переходит в

FirePropertyChanged (Выражение > Выбор свойства)

но внутри этого метода его PropertyChangedEventHandler всегда остается нулевым, что предотвращает полное выполнение метода. В конечном счете, моя сетка в представлении остается незамеченной, поскольку ее основной источник элементов был изменен.

Я что-то пропустил??

Заранее спасибо

-K9


person Ali    schedule 16.09.2010    source источник


Ответы (1)


Действительно ли ваша ViewModelBase реализовала INotifyPropertyChanged?

если да, попробуйте FirePropertyChanged со строковым параметром.

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

Кстати, вот класс INPCBase, который я использую:

/// <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
}
person blindmeis    schedule 16.09.2010