wpf 如何从用户控件触发自定义事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9226149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:17:49  来源:igfitidea点击:

How do I fire a custom event from a User Control?

wpfvb.neteventsuser-controls

提问by will0809

I have a very interesting task that I need help with. The description is as follows:

我有一项非常有趣的任务需要帮助。说明如下:

I have a user control (SomeUserControl), that I am using in a Main Window. I write my application entirely on SomeUserControl, and Main Window is hosting SomeUserControl and nothing else.

我有一个用户控件 (SomeUserControl),我在主窗口中使用它。我完全在 SomeUserControl 上编写我的应用程序,而主窗口托管 SomeUserControl 而没有其他任何内容。

Right now I have a shutdown button (in SomeUserControl), that is supposed to close the Main Window. The reason for this is that I do not want anything from SomeUserControl to close the application itself, but to fire an event from SomeUserControl, and Main Window receives it, and Main Window will close the application instead of SomeUserControl.

现在我有一个关闭按钮(在 SomeUserControl 中),它应该关闭主窗口。这样做的原因是我不希望 SomeUserControl 中的任何内容关闭应用程序本身,而是从 SomeUserControl 触发事件,并且主窗口接收它,并且主窗口将关闭应用程序而不是 SomeUserControl。

How do I do it? I am not familiar with the concept of creating and handling custom events, so if someone could explain it in words and in code as an example, I will be very grateful to you!

我该怎么做?我对创建和处理自定义事件的概念不熟悉,所以如果有人能用文字和代码为例进行解释,我将非常感激!

Edit: Here's my code so far.

编辑:到目前为止,这是我的代码。

(in Window 2)

(在窗口 2 中)

Public Event CloseApp As EventHandler

Public Event CloseApp As EventHandler

Private Sub CancelButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles CancelButton.Click
    DialogResult = False
    RaiseEvent CloseApp(Me, New EventArgs)
End Sub

(In Main Window) Public loginPage As New LoginPage

(在主窗口中)公共登录页面作为新登录页面

Public Sub New()
    InitializeComponent()
    AddHandler loginPage.CloseApp, AddressOf Me.ShutDownJobChangeWindow
End Sub

Private Sub ShutDownJobChangeWindow(ByVal sender As Object, ByVal e As EventArgs)
    Application.Current.Shutdown()
End Sub

Goal: I want to close the application when I click cancel in Window 2, but I don't want to do it in such a way that Window 2 closes itself, but by sending some notification to Main Window, and Main Window closes the application.

目标:我想在窗口 2 中单击取消时关闭应用程序,但我不想以窗口 2 自行关闭的方式执行此操作,而是通过向主窗口发送一些通知,然后主窗口关闭应用程序.

回答by Uri

If the logic of the user control is implemented in the "code behind" of the user control class, do the following.

如果用户控件的逻辑是在用户控件类的“代码隐藏”中实现的,请执行以下操作。

I'm assuming the XAML file has somewhere a button with a click event:

我假设 XAML 文件的某处有一个带有单击事件的按钮:

<Button Click="Button_Click">Close App</Button>

Then, in your code behind for SomeUserControl class, do the following:

然后,在 SomeUserControl 类背后的代码中,执行以下操作:

public partial class SomeUserControl : UserControl
{
    public event EventHandler CloseApp;

    ...

    private void Button_Click( object sender, RoutedEventArgs e )
    {
        if( CloseApp != null ) {
            CloseApp( this, new EventArgs( ) );
        }
    }
}

In your Main window, listen to the event:

在您的主窗口中,收听事件:

...

someUserCtrl.CloseApp += new EventHandler( MyFn );

private void MyFn( object sender, object EventArgs e ) {
    ...
}

回答by AkselK

The simplest way to do this is to declare a custom event:

最简单的方法是声明一个自定义事件:

public delegate void ShutdownEventHandler (object sender,  EventArgs data);
public event ShutdownEventHandler Shutdown;
protected void OnShutdown(EventArgs args)
{
    if(Shutdown != null)
        Shutdown(this, args);
}

Then you subscribe to the Shutdown event in MainWindow, and handle shutdown logic there. And in SomeUserControl, you simply run OnShutdown when you want to shutdown your application.

然后在 MainWindow 中订阅 Shutdown 事件,并在那里处理关闭逻辑。在 SomeUserControl 中,您只需在想要关闭应用程序时运行 OnShutdown。

回答by stefano

I had the same problem, and I've solved in this way:

我遇到了同样的问题,我已经通过这种方式解决了:

if you are using a softversion of MVVM (with softI mean that you use codebehind for events handling) and your event is within the ModelView class do this:

如果您使用的是版本MVVM(带我的意思是,您使用代码隐藏事件处理),你的事件是模型视图类中做到这一点:

In your MainWindow:

在您的主窗口中:

    public MainWindow(ViewModels.MyViewModel vm)
    {
        InitializeComponent();

        //pass the istance of your ViewModel to the MainWindow (for MVVM patter)
        this.vm = vm;

        //Now pass it to your User Control 
        myUserControl.vm = vm;
    }

In your UserControl

在您的用户控件中

    public partial class MyUserControl: UserControl
    {
           public ViewModels.MyViewModel  vm;

           public MyUserControl()
           {
                 InitializeComponent();
           }

           private void button_Click(object sender, RoutedEventArgs e)
           {
                 vm.MyMethod();
           }
     }

Last but not least, in your MainWindow's xaml insert your user control and give it a name:

最后但并非最不重要的是,在您的 MainWindow 的 xaml 中插入您的用户控件并为其命名:

<local:MyUserControl x:Name="myUserControl" />

<local:MyUserControl x:Name="myUserControl" />

If you don't want to use a ViewModel, you can simply pass to your UserControl an instance of your MainWindow and then you can run within the codebehind of your usercontrol all of your MainWindow's public methods.

如果您不想使用 ViewModel,您可以简单地将 MainWindow 的一个实例传递给您的 UserControl,然后您可以在您的用户控件的代码隐藏中运行所有 MainWindow 的公共方法。

Hope it will help!

希望它会有所帮助!

Sorry, the question is VB so here is the VB version of the code above:

抱歉,问题是 VB,所以这里是上面代码的 VB 版本:

MainWindow:

主窗口:

Public Sub New(ByVal vm As ViewModels.MyViewModel)
   InitializeComponent()
   Me.vm = vm
   myUserControl.vm = vm
End Sub

UserControl:

用户控件:

Public Partial Class MyUserControl
   Inherits UserControl

   Public vm As ViewModels.MyViewModel

   Public Sub New()
       InitializeComponent()
   End Sub

   Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
       vm.MyMethod()
   End Sub
End Class