Вопрос

Как я могу запустить событие с такими аксессорами:

public event EventHandler CanExecuteChanged
    {
      add
      {
        CommandManager.RequerySuggested += value;
      }
      remove
      {
        CommandManager.RequerySuggested -= value;
      }
    }

Если бы это было обычное событие, я бы запустил его:

CanExecuteChanged(sender, EventArgs..). 

Но здесь это не работает - я могу только сделать

CanExecuteChanged +=..

чтобы прикрепить метод, выполните событие, но я не могу его запустить.

Также будет оценена некоторая документация по этому вопросу.Спасибо.

РЕДАКТИРОВАТЬСобытие происходит из класса, реализующего ICommand в WPF.больше нечего показывать :).И нет - CommandManager.RequerySuggested(this, EventArgs.Empty);не работает.

РЕДАКТИРОВАТЬ2 Не знаю, что сказать — пример Джона должен был сработать, даже если метод добавления вызывается правильно — когда я пытаюсь вызвать событие, оно равно нулю :|.Я, наверное, брошу мероприятия с аксессуами.

Это было полезно?

Решение

Это событие просто подписка на другое событие и отписка от него.Если вы хотите, чтобы ваши подписчики (и только ваши подписчики, а не отдельные для другого события) для вызова, вам нужно будет хранить своих подписчиков отдельно.Например, вы можете изменить код на что-то вроде:

private EventHandler canExecuteChanged;

public event EventHandler CanExecuteChanged
{
    add
    {
        CommandManager.RequerySuggested += value;
        canExecuteChanged += value;
    }
    remove
    {
        CommandManager.RequerySuggested -= value;
        canExecuteChanged -= value;
    }
}

Другие советы

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

Лучшая страница, которую я смог найти на События против делегатов.Прочитать..

Можешь выложить фрагмент побольше..кажется что-то не так..

Убийственное обновление

Кажется, я наконец-то увидел вашу проблему и способы ее решения.Короткий ответ: Он не знает имени делегата, который будет вызываться, если вы пишете свои собственные методы доступа.Если вы этого не сделаете..компилятор добавляет частный делегат с известным именем и, следовательно, может его вызвать

Этот фрагмент кода показывает, что я имею в виду.Этот Статья MSDN показала мне свет.Отличный вопрос чувак..Я потерял 30 минут.Проголосовал за :)

public class Hash1 
    {

        private EventHandler myHomeMadeDelegate;
        public event EventHandler FancyEvent
        {
            add
            {
                //myDelegate += value;
                myHomeMadeDelegate = (EventHandler)Delegate.Combine(myHomeMadeDelegate, value);
            }
            remove
            {
                //myDelegate -= value;
                myHomeMadeDelegate = (EventHandler)Delegate.Remove(myHomeMadeDelegate, value);
            }
        }
        public event EventHandler PlainEvent;


        public Hash1()
        {
            FancyEvent += new EventHandler(On_Hash1_FancyEvent);
            PlainEvent += new EventHandler(On_Hash1_PlainEvent);

            // FancyEvent(this, EventArgs.Empty);  //won't work:What is the backing delegate called? I don't know
            myHomeMadeDelegate(this, EventArgs.Empty); // Aha!
            PlainEvent(this, EventArgs.Empty);
        }

        void On_Hash1_PlainEvent(object sender, EventArgs e)
        {
            Console.WriteLine("Bang Bang!");
        }

        void On_Hash1_FancyEvent(object sender, EventArgs e)
        {
            Console.WriteLine("Bang!");
        }
}

Хорошо, я обнаружил, что если я хочу вызвать это событие, вам нужно сделать:

CommandManager.InvalidateRequerySuggested();.

Вам нужно напрямую вызывать базовые события.В вашем случае это выглядит так:

<blockquote>CommandManager.RequerySuggested(sender, EventArgs.…)</blockquote>

/РЕДАКТИРОВАТЬ:ок, я этого не заметил CommandManager это класс фреймворка.В данном случае вы явно не хотите делать то, что я предложил.Решение Джона по существу:Вы должны отслеживать свое собственное событие и вызывать его (например.в качестве делегата).В соответствии с примером Джона вызов будет выглядеть так:

canExecuteChanged(sender, EventArgs.Empty);

вау, только что были похожие проблемы.Ответ, который помог мне понять, примерно такой: Гишу.

Также из спецификаций C#, http://www.microsoft.com/en-us/download/details.aspx?id=7029, в разделе «10.8.1 События, подобные полю», написано: «При компиляции события, подобного полю, компилятор автоматически создает хранилище для хранения делегата».

в характеристиках также написано:

Таким образом, объявление события экземпляра вида:

class X
{
   public event D Ev;
}

может быть скомпилировано во что-то эквивалентное:

class X
{
   private D __Ev;  // field to hold the delegate

   public event D Ev {
      add {
         lock(this) { __Ev = __Ev + value; }
      }

      remove {
         lock(this) { __Ev = __Ev - value; }
      }
   }
}

Если вы сделаете что-то вроде кода ниже, компилятор успешно его скомпилирует:

namespace ConsoleApplication1
{    
    class Program 
    {
        public event EventHandler ss;

        Program()
        {
            if (null != ss)
            {
                ss(this, EventArgs.Empty) ;

            }
        }

        static void Main(string[] args)
        {
            new Program();
        }
    }
}

И если вы добавите средства доступа к ss выше, он НЕ скомпилируется:

namespace ConsoleApplication1
{    
    class Program 
    {
        public event EventHandler ss
        {
            add { }
            remove { }
        }

        Program()
        {
            if (null != ss)
            {
                ss(this, EventArgs.Empty) ;

            }
        }

        static void Main(string[] args)
        {
            new Program();
        }
    }
}

Здесь показаны два типа событий.

  1. Полевые события => мы можем вызывать
  2. события с аксессорами => мы не можем вызывать (не могу найти это в спецификациях, почему, возможно, я это пропустил) (и тестировал это только в Visual Studio 2005, и, я думаю, спецификации были самыми последними)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top