Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将原始处理程序的事件参数传递给wpf中的路由事件_C#_Wpf_Wpf Controls - Fatal编程技术网

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