如何从同一个类中的静态函数调用公共事件?

发布于 2024-12-03 20:42:58 字数 2782 浏览 1 评论 0原文

我有一个类,其中包含另一个类的 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));
    }
}

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

我尝试了很多很多事情,例如:

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

  • 将 public static void PropertyChanged 更改为非静态版本,但这会出现错误在所有 UIPropertyMetadata(PropertyChanged)) 部件上显示此错误消息:“非静态字段、方法或属性需要对象引用”

  • 还有更多,但全部

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

I have a class that contains an ObservableCollection of another class. I want to be notified if one of the class members is changed, because I need to do some calculating in the MediaCollection class. So I added an event to that class:

public event PropertyChangedEventHandler PropertyChangedEvent;

which is called in this collection class:

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

The MediaEntry class looks something like this:

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

This call will notify the UI, etc. but to raise event to the container class I need to raise my PropertyChangedEvent (which is listened for in the container class). According to documentation I need to add these lines:

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

Which I need to call from the public static void PropertyChanged function. However, and here is the real question, how can I call the public event from within my static function?

I have tried many, many things like:

  • Changing the public event PropertyChangedEventHandler to a public static event. This will give an error like this: "Member MediaEntry.PropertyChangedEvent cannot be accessed with an instance reference; qualify it with a type name instead"

  • Changing the public static void PropertyChanged to a non-static version, but this will give errors on all UIPropertyMetadata(PropertyChanged)) parts with this error message: "An object reference is required for the non-static field, method, or property"

  • And some more, but all to no avail.

I somehow figure that I need delegates here, but don't now how or where to start. Any help is greatly appreciated in solving my problem here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

星軌x 2024-12-10 20:42:58

当您注册 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 的​​许多不同组合时感到困惑:-)。

When you register the IsError DependencyProperty passing it the UIPropertyMetadata, you are setting the method that will be called when the property will change. In your case it is

public static void PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)

The instance for which the property has changed is passed as obj to this method, and in the args you find the property that changed and the old and new value. This meis the place where you have to call your event. You are just missing the implementation of ObjectPropertyChanged, which is not static, since you are using the argument passed to your PropertyChanged method casted to MediaEntry. The implementation is similar to what you tried with PropertyEventChanged, the only difference being the fact that it is not static and that you don't pass any object to it:

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

BTW I would try to use better names, since it is very easy to get confused when you read PropertyEventChanged and PropertyChangedEvent and many different combination of Property and Changed :-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文