Как использовать пользовательские 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, это вызовет исключение.