Как вызвать публичное событие из статической функции в том же классе? - PullRequest
4 голосов
/ 08 сентября 2011

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

, которые мне нужно вызывать из общедоступной статической функции void PropertyChanged.Однако, и вот реальный вопрос, как я могу вызвать публичное событие из моей статической функции?

Я пробовал много, много вещей, таких как:

  • Изменениепубличное событие PropertyChangedEventHandler для публичного статического события.Это приведет к ошибке, подобной этой: «Член MediaEntry.PropertyChangedEvent не может быть доступен со ссылкой на экземпляр; вместо этого укажите его имя типа»

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

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

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

1 Ответ

2 голосов
/ 08 сентября 2011

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

public static void PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs 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: -).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...