Как использовать пользовательские RoutedEventArgs с событием нажатия MenuItem

Я новичок в C# / WPF, пытаюсь разработать приложение в архитектуре MVVC. У меня есть некоторые классы, которые составляют мой DAL (они ссылаются на localdb с EF), и у меня есть некоторые классы, которые составляют ViewController. Объекты ViewController заполняются методом, который использует объект DAL в качестве параметра, который запрашивает Db для заполнения некоторых ObservableCollections, которые в конечном итоге привязываются к DataGrids в моем пользовательском интерфейсе. Объекты ViewController привязываются к объектам DAL с помощью событий, так что каждый раз, когда объект DAL записывает изменения в Db, ViewController перезапускает метод обновления, и, таким образом, пользовательский интерфейс заполняется новыми данными.

Я хочу использовать событие MenuItem_click, чтобы вызвать изменения в БД, а затем сделать так, чтобы пользовательский интерфейс отражал это. Используя существующую структуру, я думаю, что мне нужно как-то передать объект DAL в обработчик MenuItem_click, чтобы ViewController был уведомлен об изменениях в Db и обновлялся соответствующим образом. Точно так же, если бы я создал новый объект DAL в обработчике события click, мне нужно было бы передать объект ViewController, чтобы он мог быть связан с новым объектом DAL - такая же проблема.

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

Я создал производный пользовательский класс RoutedEventArgs (где DbSymbol - это объект DAL):

    public class ClearAllEventArgs : RoutedEventArgs
    {
        private DbSymbol _symbolDAL { get; set; }
        public DbSymbol symbolDAL { get { return _symbolDAL; } }

        public ClearAllEventArgs(RoutedEvent routedEvent, DbSymbol dbSymbol) : base(routedEvent)
        {
            this._symbolDAL = dbSymbol;
        }
    }

    private void clearAllDataMenuItem_Click(object sender, ClearAllRoutedEventArgs e)
    {
        MessageBoxResult confirmDelete= MessageBox.Show("This will remove all data from the database. Continue?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);
        if (confirmDelete == MessageBoxResult.Yes)
        {
            e.symbolDAL.RemoveAll();
        }
    }

Но раньше я использовал XAML для подключения обработчика событий (который был присоединен к.Click автоматически с помощью Click="ClearAllMenuItem_Click" и волшебным образом сгенерировал RoutedEventArgs), и я не могу точно понять, что происходило за кулисами, чтобы дублировать его я с code-behind, который, я полагаю, необходим для чего-то подобного.

Вот что я попробовал:

            RoutedEvent MouseClickEvent = EventManager.RegisterRoutedEvent("Clear All", RoutingStrategy.Bubble, typeof(RoutedEventArgs), typeof(MenuItem));
            ClearAllEventArgs newClearAll = new ClearAllEventArgs(MouseClickEvent, symbolDAL);
            clearAllDataMenuItem.Click += clearAllDataMenuItem_Click(this, newClearAll);

Что даже не скомпилируется, так как clearAllDataMenuItem_Click возвращает тип void, но clearAllDataMenuItem.Click требует RoutedEventHandler. Я довольно новичок в событиях в целом, поэтому, пожалуйста, прости мое невежество. Может кто-нибудь помочь или направить меня в правильном направлении?

Спасибо!

1 ответ

Решение

Вместо того, чтобы пытаться сделать это в событиях, вы можете сделать это с отправителем. (Я не уверен, как именно ваш MenuItem подключен, но это должно дать вам общее представление.

Отправителем в вашем случае является FrameworkElement, и все FrameworkElements имеют свойство Tag.

Итак, в вашем XAML вы делаете что-то вроде этого:

<MenuItem Tag="{Binding}"></MenuItem>

Тогда в случае вы можете что-то вроде этого:

private void clearAllDataMenuItem_Click(object sender, RoutedEventArgs e)
{
    var symbolDAL = (SymbolDAL)((FrameworkElement) sender).Tag;

    MessageBoxResult confirmDelete = MessageBox.Show("This will remove all data from the database. Continue?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);
    if (confirmDelete == MessageBoxResult.Yes)
    {
        symbolDAL.RemoveAll();
    }
}

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

Другие вопросы по тегам