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

时间:2012-02-10 10:18:34

标签: wpf vb.net events user-controls

我有一个非常有趣的任务,我需要帮助。描述如下:

我有一个用户控件(SomeUserControl),我在主窗口中使用它。我完全在SomeUserControl上编写我的应用程序,主窗口正在托管SomeUserControl,没有别的。

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

我该怎么办?我不熟悉创建和处理自定义事件的概念,所以如果有人能用文字和代码解释它,我将非常感谢你!

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

(在窗口2中)

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

(在主窗口中)     公共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

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

3 个答案:

答案 0 :(得分:15)

如果用户控件的逻辑在"后面的代码中实现"在用户控件类中,执行以下操作。

我假设XAML文件中有一个带有点击事件的按钮:

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

然后,在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( ) );
        }
    }
}

在主窗口中,收听事件:

...

someUserCtrl.CloseApp += new EventHandler( MyFn );

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

我遇到了同样的问题,并且已经通过以下方式解决了:

如果您使用的是MVVM的 soft 版本(与 soft 一起使用,则表示您使用代码隐藏进行事件处理),并且您的事件是在ModelView类中执行以下操作:

在您的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;
    }

在您的UserControl中

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

           public MyUserControl()
           {
                 InitializeComponent();
           }

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

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

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

如果您不想使用ViewModel,只需将MainWindow的一个实例传递给UserControl,然后就可以在userControl的代码内运行所有MainWindow的所有公共方法。

希望这会有所帮助!

对不起,问题是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