Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing Event Arguments of original handler to Routed Event in wpf

The following code shows a normal event and a routed event. Here I have used the same event name for explaining purposes but in reality I am using just the routed event.

//Normal Event
public event SelectedHandler Selected;
public delegate void SelectedHandler(Object Sender, RoutedEventArgs e);

//Routed Event
public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent(
"Selected", RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyUserControl));

//add remove handlers
public event RoutedEventHandler Selected
{
    add { AddHandler(SelectedEvent, value); }
    remove { RemoveHandler(SelectedEvent, value); }
}

I am raising these events from a couple of event handlers as follows

private void lstvMyView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    //Normal Event Raise
    if (Selected != null)
        Selected(this, e);

    //Routed Event Raise
    RoutedEventArgs args = new RoutedEventArgs(SelectedEvent);
    RaiseEvent(args);
}

private void lstvMyView_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    //Normal Event Raise
    if (Selected != null)
        Selected(this, e);

    //Routed Event Raise
    RoutedEventArgs args = new RoutedEventArgs(SelectedEvent);
    RaiseEvent(args);
}

When I am handling the normal Event I am able to send the args of both the handlers to the event but in Routed Event the args will be a new instance. I want to pass the args of both the handlers to the Routed Event. Is it possible to achieve this? If yes then how?

like image 355
samar Avatar asked Dec 10 '22 12:12

samar


1 Answers

first of all you do not need this (and should remove it):

//Normal Event
public event SelectedHandler Selected;
public delegate void SelectedHandler(Object Sender, RoutedEventArgs e);

i.e. you do not need to define a separate "normal" event, because you have already done it with this declaration:

public event RoutedEventHandler Selected
{
    add { AddHandler(SelectedEvent, value); }
    remove { RemoveHandler(SelectedEvent, value); }
}

with the above code block you are "wrapping" the routed event with a "normal" (clr) one so the users of your class can use it with the "normal" syntax (i.e. instanceOfMyUserControl.Selected += ....)

second, if you want the event arguments of your routed event to be the same as the ones of the SelectionChanged event of the the ListView you are listening to, you should declare your routed event this way:

public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent(
"Selected", RoutingStrategy.Bubble,
typeof(SelectionChangedEventHandler),
typeof(MyUserControl));

//add remove handlers
public event SelectionChangedEventHandler Selected
{
    add { AddHandler(SelectedEvent, value); }
    remove { RemoveHandler(SelectedEvent, value); }
}

Notice that I have substituted the RoutedEventHandler with SelectionChangedEventHandler, as it is the predefined one that can "carry" SelectionChangedEventArgs.

Now for the rising of the event. You do not need to rise both the "normal" and the routed one (as the "normal" is a wrapper for the routed), so you should delete this:

//Normal Event Raise
if (Selected != null)
    Selected(this, e);

and rise only the routed version, which can be done this way:

SelectionChangedEventArgs args = 
    new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);

RaiseEvent(args);

Notice that I am using the event arguments from the original event to set the AddedItems and RemovedItems of the one custom one.

like image 129
xenry Avatar answered May 20 '23 14:05

xenry