I am new to C# / WPF, trying to develop an application in MVVC architecture. I have some classes that make up my DAL, (they reference a localdb with EF), and I have some classes that make up the ViewController. The ViewController objects are populated with a method that uses a DAL object as a parameter, which queries the Db to populate some ObservableCollections, which are finally bound to DataGrids in my UI. The ViewController objects are bound to the DAL objects using events, such that anytime a DAL object writes changes to the Db, the ViewController reruns the update method, and thus the UI is repopulated with new data.

I want to use a MenuItem_click event to cause changes to the Db, and then have the UI reflect this. Using the existing structure, I think I would somehow need to pass the DAL object into the MenuItem_click handler, so that the ViewController will be notified of changes to the Db and update accordingly. Similarly, if I created a new DAL object in the click event handler, I would need to pass in the ViewController object so it could be bound to the new DAL object--so same problem.

I'm having trouble figuring out how to pass additional arguments into the MenuItem_click handler.

I created a derived custom RoutedEventArgs class (where DbSymbol is the DAL object):

    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();
        }
    }

But I was using XAML to connect the event handler before (which attached to .Click automatically with Click="ClearAllMenuItem_Click" and magically auto-generated the RoutedEventArgs), and I can't figure exactly what was going on behind the scenes to duplicate it myself with code-behind, which I assume is necessary for something like this.

This is what I have tried:

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

Which will not even compile, since clearAllDataMenuItem_Click returns void type, but clearAllDataMenuItem.Click requires RoutedEventHandler. I'm fairly new to Events in general, so please forgive my ignorance. Can someone help, or point me in the right direction?

Thanks!

有帮助吗?

解决方案

Instead of trying to do it in the events you can do it with the sender. (I'm not sure exactly how your MenuItem is wired up, but this should give you the general idea.

The sender in your case is a FrameworkElement and all FrameworkElements have a Tag property.

So in your XAML you do do something like this:

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

Then in the event you can something like this:

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();
    }
}

Make sure to add the error handling because if that tag isn't your object or null it will cause an exception.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top