【问题标题】:How to call a public event from a static function in the same class?如何从同一类中的静态函数调用公共事件?
【发布时间】:2011-09-07 22:44:35
【问题描述】:

我有一个包含另一个类的 ObservableCollection 的类。如果其中一个类成员发生更改,我希望得到通知,因为我需要在 MediaCollection 类中进行一些计算。所以我在那个类中添加了一个事件:

public event PropertyChangedEventHandler PropertyChangedEvent;

在这个集合类中被调用:

public class MediaCollection : INotifyPropertyChanged
{
    private List<MediaEntry> ModifiedItems = new List<MediaEntry>();
    private ObservableCollection<MediaEntry> tagList = new ObservableCollection<MediaEntry>();

    public MediaCollection()
    {
        tagList = new ObservableCollection<MediaEntry>();
        tagList.CollectionChanged += CollectionChangedHandler;
    }

    public void CollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
    {
            foreach (MediaEntry newItem in e.NewItems)
            {
                ModifiedItems.Add(newItem);
                newItem.PropertyChangedEvent += OnItemPropertyChanged;
            }
    ...
    }

    public void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        MediaEntry item = sender as MediaEntry; 
        if (item != null)       
            ModifiedItems.Add(item);
    }

MediaEntry 类看起来像这样:

public class MediaEntry : DependencyObject
{
    public event PropertyChangedEventHandler PropertyChangedEvent;

    public bool IsError
    {
        get { return (bool)GetValue(IsErrorProperty); }
        set { SetValue(IsErrorProperty, value); }
    }
    public static readonly DependencyProperty IsErrorProperty =
        DependencyProperty.Register("IsError", typeof(bool), typeof(MediaEntry), new 
        UIPropertyMetadata(PropertyChanged));

    public static void PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (obj is MediaEntry)
        {
            ((MediaEntry)obj).ObjectPropertyChanged(args);
        }
    }

此调用将通知 UI 等,但要向容器类引发事件,我需要引发我的 PropertyChangedEvent(在容器类中侦听)。根据文档,我需要添加以下几行:

public static void PropertyEventChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    PropertyChangedEventHandler handler = PropertyChangedEvent;
    if (handler != null)
    {
        handler(obj, new PropertyChangedEventArgs(args.Property.Name));
    }
}

我需要从公共静态 void PropertyChanged 函数调用。但是,真正的问题是,如何从我的静态函数中调用公共事件?

我已经尝试了很多很多东西,例如:

  • 将公共事件 PropertyChangedEventHandler 更改为公共静态事件。这将给出如下错误:“无法使用实例引用访问成员 MediaEntry.PropertyChangedEvent;改为使用类型名称对其进行限定”

  • 将 public static void PropertyChanged 更改为非静态版本,但这将在所有 UIPropertyMetadata(PropertyChanged)) 部分上产生错误,并显示以下错误消息:“非静态字段需要对象引用,方法或属性”

  • 还有更多,但都无济于事。

我不知何故认为我需要代表在这里,但现在不知道如何或从哪里开始。非常感谢您在这里解决我的问题的任何帮助。

【问题讨论】:

    标签: c# wpf events observablecollection inotifypropertychanged


    【解决方案1】:

    当您注册 IsError DependencyProperty 并将其传递给 UIPropertyMetadata 时,您正在设置将在属性更改时调用的方法。在你的情况下是

    public static void PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    

    属性已更改的实例作为 obj 传递给此方法,并在 args 中找到已更改的属性以及旧值和新值。这是您必须调用活动的地方。您只是缺少 ObjectPropertyChanged 的​​实现,它不是静态的,因为您正在使用传递给您的 PropertyChanged 方法的参数转换为 MediaEntry。该实现类似于您使用 PropertyEventChanged 尝试的实现,唯一的区别是它不是静态的并且您不向它传递任何对象:

    public void ObjectPropertyChanged(DependencyPropertyChangedEventArgs args)
    {
        PropertyChangedEventHandler handler = PropertyChangedEvent;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(args.Property.Name));
        }
    }
    

    顺便说一句,我会尝试使用更好的名称,因为当您阅读 PropertyEventChanged 和 PropertyChangedEvent 以及 Property 和 Changed 的​​许多不同组合时很容易混淆:-)。

    【讨论】:

    • 您刚刚拯救了这一天!我对被调用的 OnPropertyChanged 完全视而不见(是的,我已经有了它,但在代码中没有提到)。从那里我可以举办我的活动,一切都像魅力一样。非常感谢弗朗切斯科。
    • 是的,我应该更改我的属性名称,因为无论如何这可能是这个问题的开始!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 2017-11-15
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多