C# 将原始处理程序的事件参数传递给wpf中的路由事件
以下代码显示正常事件和路由事件。在这里,我使用了相同的事件名称来进行解释,但实际上我只使用了路由事件C# 将原始处理程序的事件参数传递给wpf中的路由事件,c#,wpf,wpf-controls,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 = EventM
//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); }
}
我从以下几个事件处理程序引发这些事件
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);
}
当我处理普通事件时,我能够将两个处理程序的args发送到事件,但在路由事件中,args将是一个新实例。我想将两个处理程序的参数传递给路由事件。有可能做到这一点吗?如果是,则如何操作?首先,您不需要此功能(并且应将其删除): i、 e.您不需要定义单独的“正常”事件,因为您已经使用此声明进行了定义:
public event RoutedEventHandler Selected
{
add { AddHandler(SelectedEvent, value); }
remove { RemoveHandler(SelectedEvent, value); }
}
使用上述代码块,您正在使用“正常”(clr)代码块“包装”路由事件,以便您的类的用户可以使用“正常”语法(即instanceOfMyUserControl.Selected+=…
)
其次,如果希望路由事件的事件参数与正在侦听的ListView
的SelectionChanged
事件的事件参数相同,则应通过以下方式声明路由事件:
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); }
}
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
private void lstvMyView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
}
请注意,我用SelectionChangedEventHandler
替换了RoutedEventHandler
,因为它是可以“携带”SelectionChangedEventArgs
的预定义文件
现在让我们来关注这一事件的兴起。
您不需要同时升高“正常”和路由(因为“正常”是路由的包装),因此您应该删除以下内容:
//Normal Event Raise
if (Selected != null)
Selected(this, e);
并仅提升路由版本,可通过以下方式完成:
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); }
}
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
private void lstvMyView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
}
请注意,我正在使用原始事件的事件参数来设置一个自定义事件的
AddedItems
和RemovedItems
。要关注您的最后一条评论(可以提供特定评论的链接吗?),我将编写另一个答案,以便人们可以关注
我认为你完全没有抓住事情的要害。您希望事件的处理程序在接收时知道什么?这通常是事件参数的目的-您将一些信息传递给处理程序,并用这些信息提供确切发生的情况的背景信息
因此,当你第一次举办活动时,你会这样做:
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); }
}
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
private void lstvMyView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, e.RemovedItems, e.AddedItems);
RaiseEvent(args);
}
首先必须构造参数,然后使用带有该参数的RaiseEvent()
函数,因为要引发wpf的特殊路由类型的事件。参数必须是继承RoutedEventArgs的类的实例。请注意,您正在构造wpf中定义的SelectionChangedEventArgs
,以“携带”事件处理程序的附加信息,即哪些项已从选择中删除,哪些项已添加,因此当处理程序接收到事件时,如果需要,它可以使用该信息。
关于这一点,我认为你正在做:
//Normal Event Raise
if (Selected != null)
Selected(this, e);
基本上-(正如我在第一个回答中所说)移除它,你不需要它
因此,困扰你的是你第二次提出这项活动。这是你必须做的一个原型:
private void lstvMyView_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, ?, ?);
RaiseEvent(args);
}
如您所见,您必须再次构造SelectionChangedEventArgs
并使用RaiseEvent()
函数来引发事件。但是这次您不能使用e.RemovedItems
和e.AddedItems
,因为您正在处理MouseLeftButtonUp
事件,该事件(通过其args)携带有关鼠标状态的信息,而不是哪些项目已添加到选择中(毕竟是鼠标事件,而不是选择事件)。
你必须决定用什么来代替这两个问号——正如我在第一个答案的评论中所说,你必须决定你想向活动的用户传达什么信息。什么意思是鼠标按钮不再位于“lstvMyView”上?最简单的做法是:
SelectionChangedEventArgs args =
new SelectionChangedEventArgs(SelectedEvent, Enumerable.Empty<object>(), Enumerable.Empty<object>());
RaiseEvent(args);
SelectionChangedEventArgs参数=
新建SelectionChangedEventArgs(SelectedEvent,Enumerable.Empty(),Enumerable.Empty());
RaiseEvent(args);
通过它,您将引发事件,并告诉其消费者没有从选择中删除任何项目,也没有添加任何项目。@xenry您的解决方案非常好。这里有几件事。1.我创建了两个相同类型的事件来解释我的场景。实际上,我没有使用2个事件。2.SelectionChangedEventArgs类没有接受1个参数的构造函数。构造函数有一个重载,它将AddedItems和RemovedItems作为参数。所以你可以稍微更新一下你的答案,这样其他人也可以从中受益。3.如果我的路由事件是从两个不同的事件处理程序引发的,并且它们的EventArg不同,该怎么办?请帮忙!啊,应该检查默认构造函数,谢谢你指出。我无法理解你的问题(3),为了引发路由事件,你只需要构建SelectionChangedEventArgs,也许你可以详细说明一下?我不是说引发事件。我的意思是,如果两个处理程序的EventArg不同,如何将两个不同处理程序的EventArg传递给单个事件?例如,在我们的示例中,如果“选定”RouteEvent从2个处理程序中引发。一个处理程序有say SelectionChangedEventArgs,另一个处理程序有say MouseButtonEventArgs,那么我如何将事件参数传递给所选RoutedEvent?我希望我现在说清楚了?好吧,首先定义你的意图——即当你收到(比如说)“鼠标下移”事件时应该发生什么。如果这意味着向选择中添加一项并删除一项,则以这种方式构造参数-new SelectionChangedEventArgs(SelectedEvents,new object[]{removed},new object[]{added})。如果这意味着只向选择中添加-使用这些参数引发事件-新建SelectionChangedEventArgs(SelectedEvents,Enumerable.Empty(),new object[]{added})等等。so@xen