How do I fire a custom event from a User Control?
Asked Answered
T

3

13

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.

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.

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)

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.

Threemaster answered 10/2, 2012 at 10:18 Comment(0)
E
16

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:

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

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

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 ) {
    ...
}
Encomium answered 10/2, 2012 at 10:36 Comment(2)
like the solution AkselK provided, how do I do it in VB? especially the part in If(CloseApp != null). Because intellisense just can't find CloseApp. – will0809 20 mins agoThreemaster
I am having the same question but I am using MVVM, so i cannot use this :- someUserCtrl.CloseApp += new EventHandler( MyFn ); Rather i used MVVM Light libraries and added an event trigger to my MainWindow as <i:EventTrigger EventName="CloseApp"><cmd:EventToCommand Command="{Binding CloseAppCommand PassEventArgsToCommand="True" /></i:EventTrigger></i:Interaction.Triggers> But it does not work.Direful
S
3

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.

Seer answered 10/2, 2012 at 10:32 Comment(3)
I am converting this to VB for those who need it. Public Delegate Sub ShutdownEventHandler(sender As Object, e As EventArgs) Public Event ShutItDown As ShutdownEventHandler Public Event ShutItDown As ShutdownEventHandler but I am not too sure about the third part. Intellisense doesn't recognize "ShutItDown" inside the If statement.Threemaster
also, I am going to read up on how to subscribe to the shutdown event, because I don't know how to. If you can explain it in double quick time it will be great.Threemaster
There is no need to define ShutdownEventHandler here, since it is identical to System.EventHandler. The event declaration could simply be written as public event EventHandler Shutdown;.Erikerika
M
0

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

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

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:

<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.

Hope it will help!

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

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
Meatus answered 5/11, 2018 at 20:11 Comment(1)
Note that the question is tagged vb.net, but the code samples here are in C#.Incisure

© 2022 - 2024 — McMap. All rights reserved.