Как вызвать публичное событие из статической функции того же класса?

У меня есть класс, содержащий 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);
        }
    }

Этот вызов будет уведомлять пользовательский интерфейс и т. Д., Но чтобы вызвать событие в классе контейнера, мне нужно поднять мое 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 нельзя получить доступ с помощью ссылки на экземпляр; вместо этого укажите его именем типа»

  • Изменение общедоступного статического void PropertyChanged на нестатическую версию, но это приведет к ошибкам во всех частях UIPropertyMetadata (PropertyChanged)) с таким сообщением об ошибке: «Для нестатического поля, метода или свойства требуется ссылка на объект»

  • И еще несколько, но все безрезультатно.

Я почему-то полагаю, что здесь мне нужны делегаты, но не знаю, как и с чего начать. Приветствуется любая помощь в решении моей проблемы здесь.


person riesm    schedule 07.09.2011    source источник


Ответы (1)


Когда вы регистрируете IsError DependencyProperty, передавая ему UIPropertyMetadata, вы устанавливаете метод, который будет вызываться при изменении свойства. В вашем случае это

public static void PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)

Экземпляр, для которого свойство было изменено, передается этому методу как obj, и в аргументах вы найдете свойство, которое изменилось, а также старое и новое значение. Это место, где нужно назвать свое мероприятие. Вам просто не хватает реализации 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 :-).

person Francesco Baruchelli    schedule 08.09.2011
comment
Вы только что спасли положение! Я был полностью слеп к OnPropertyChanged, который был вызван (и да, он у меня уже был, но не упоминается здесь в коде). Оттуда я могу поднять свое мероприятие, и все работает как шарм. Большое спасибо Франческо. - person riesm; 08.09.2011
comment
И да, я должен изменить имена своих свойств, так как это могло быть началом проблемы! - person riesm; 08.09.2011