将原始处理程序的Event Arguments传递给wpf中的Routed Event

sam*_*mar 4 c# wpf wpf-controls

以下代码显示正常事件和路由事件.在这里,我使用相同的事件名称来解释目的,但实际上我只使用路由事件.

//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); }
}
Run Code Online (Sandbox Code Playgroud)

我正在从几个事件处理程序中提取这些事件,如下所示

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);
}
Run Code Online (Sandbox Code Playgroud)

当我处理正常事件时,我能够将两个处理程序的args发送到事件,但在Routed Event中,args将是一个新实例.我想将两个处理程序的args传递给Routed Event.是否有可能实现这一目标?如果是,那怎么样?

xen*_*nry 12

首先你不需要这个(并且应该删除它):

//Normal Event
public event SelectedHandler Selected;
public delegate void SelectedHandler(Object Sender, RoutedEventArgs e);
Run Code Online (Sandbox Code Playgroud)

即,您不需要定义单独的"正常"事件,因为您已经使用此声明完成了它:

public event RoutedEventHandler Selected
{
    add { AddHandler(SelectedEvent, value); }
    remove { RemoveHandler(SelectedEvent, value); }
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码块,你用"普通"(clr)"包装"路由事件,这样你的类的用户就可以使用"普通"语法(即instanceOfMyUserControl.Selected += ....)

第二,如果您希望路由事件的事件参数SelectionChangedListView您正在侦听的事件的事件参数相同,则应以这种方式声明路由事件:

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); }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经替换了RoutedEventHandlerwith SelectionChangedEventHandler,因为它是可以"携带"的预定义的SelectionChangedEventArgs.

现在为了这个事件的崛起.你不需要同时升级"正常"和路由(因为"正常"是路由的包装),所以你应该删除它:

//Normal Event Raise
if (Selected != null)
    Selected(this, e);
Run Code Online (Sandbox Code Playgroud)

并且只上升路由版本,可以这样做:

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

RaiseEvent(args);
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用原始事件中的事件参数来设置AddedItemsRemovedItems自定义的事件参数.