开发者

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

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 Ob开发者_C百科servableCollection<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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜