How to call a public event from a static function in the same class?

守給你的承諾、 提交于 2021-02-07 17:31:28

问题


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.


回答1:


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 :-).



来源:https://stackoverflow.com/questions/7341368/how-to-call-a-public-event-from-a-static-function-in-the-same-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!