Question

I'm stuck. I am trying to AddHandler for a button on Page1 such that when the button is clicked it will AddHandler to the MainWindow_MouseUp event, so I can click anywhere on the MainWindow to show a message.

How can I fix this problem?


Notes:

  • I have removed the Handler for MainWindow_MouseUp on MaindWindow_load event, so the message will no show on load of MainWindow.
  • I have a frame showing Page1.
  • When a button in Page1 is clicked, it's supposed to AddHandler, so MainWindow_MouseUp will show a message when MainWindow executes the MainWindow_MouseUp event.

Page1.xaml

<Page x:Class="Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="300"
    Title="Page1" Background="Red">
    <Grid>
        <Button Content="AddHandler for MainWindow MouseUp message"
                Height="42"
                HorizontalAlignment="Left"
                Margin="0,126,0,0"
                Name="Button1"
                VerticalAlignment="Top"
                Width="300" />
        <TextBlock Height="84"
                   HorizontalAlignment="Left"
                   Margin="80,184,0,0"
                   Name="TextBlock1"
                   Text="The button will add a handler in order to show a message on the MainWindow MouseUp event"
                   VerticalAlignment="Top"
                   Width="151"
                   TextWrapping="Wrap" />
        <TextBlock Height="23"
                   HorizontalAlignment="Left"
                   Margin="12,56,0,0"
                   Name="TextBlock2"
                   Text="Page1"
                   VerticalAlignment="Top" />
    </Grid>
</Page>

Page1.vb

Class Page1

    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.Windows.RoutedEventArgs) _
                              Handles Button1.Click

        Dim _MainWindow As New MainWindow
        AddHandler _MainWindow.MouseUp, AddressOf Button1_Click

    End Sub

End Class

MainWindow.xaml

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Frame Source="Page1.xaml"
               Height="300"
               HorizontalAlignment="Left"
               Margin="110,-1,0,0"
               Name="Frame1"
               VerticalAlignment="Top"
               Width="300" />

        <TextBlock Height="144"
                   HorizontalAlignment="Left"
                   Margin="0,48,0,0"
                   Name="TextBlock2"
                   Text="Click here to show a message if handler MainWindow MouseUp is added from page1"
                   VerticalAlignment="Top"
                   TextWrapping="Wrap"
                   Width="104"
                   Foreground="#FF003AFF" />
        <TextBlock Height="153"
                   HorizontalAlignment="Left"
                   Margin="416,159,0,0"
                   Name="TextBlock3"
                   Text="Click here to show a message if handler MainWindow MouseUp is added from page1"
                   VerticalAlignment="Top"
                   TextWrapping="Wrap"
                   Foreground="#FFEF00FF" />
    </Grid>
</Window>

MainWindow.vb

Public Class MainWindow

    Private Sub Window_Loaded(ByVal sender As System.Object, _
                              ByVal e As System.Windows.RoutedEventArgs) _
                              Handles MyBase.Loaded

        RemoveHandler Me.MouseUp, AddressOf MainWindow_MouseUp

    End Sub
    Private Sub MainWindow_MouseUp(ByVal sender As Object, _
                                   ByVal e As MouseEventArgs) _
                                   Handles Me.MouseUp
        Test1()

    End Sub

    Public Sub Test1()
        MessageBox.Show("AddHandler added from page 1 was successful!")
    End Sub

End Class
Was it helpful?

Solution

This is just all a bit confused. Let's look at what you are doing :

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
                           System.Windows.RoutedEventArgs) Handles Button1.Click
    Dim _MainWindow As New MainWindow
    AddHandler _MainWindow.MouseUp, AddressOf Button1_Click
End Sub

This is making a new MainWindow and is linking its MouseUp event to the method Button1_Click - you're telling _MainWindow to execute Page1's Button1_Click method when it fires its MouseUp event. I suspect this is not what you want to do.

Now this :

RemoveHandler Me.MouseUp, AddressOf MainWindow_MouseUp

tells me that you don't want MainWindow_MouseUp to be hooked up right away. You can get rid of this line simply by removing the Handles clause like :

Private Sub MainWindow_MouseUp(ByVal sender As Object, _
                                ByVal e As MouseEventArgs) 'Handles Me.MouseUp
   Test1()
End Sub

Now there's nothing to remove.

So... we're back to the problem of notifying MainWindow that Page1's button has been clicked. To do this, add an event to Page1 :

Class Page1
    Shared Event PageButtonClick(sender As Object, e As RoutedEventArgs)

    Private Sub Button1_Click(sender As System.Object, e As _
                         System.Windows.RoutedEventArgs) Handles Button1.Click
        RaiseEvent PageButtonClick(sender, e)
    End Sub
End Class

I've made the event shared here - this allows us to link it up without creating an instance of the page in MainWindow (ie: you can simply have a frame using Page1 as source). What we're doing here is raising a PageButtonClick event in Page1 when Button1 has been clicked.

In your main window, then :

Class MainWindow

    Private Sub Window_Loaded(sender As System.Object, e As _
                          System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        'Here we listen for the Page1Click event and execute the method
        'Page1_Clicked when we hear it
        AddHandler Page1.PageButtonClick, AddressOf Page1_Clicked
    End Sub

    Private Sub Window_MouseUp(sender As System.Object, e As _
                                     System.Windows.Input.MouseButtonEventArgs)
        MessageBox.Show("Hello")
    End Sub

    Private Sub Page1_Clicked(sender As Object, e As RoutedEventArgs)
        'When we get a click from Page1, add a handler to this window's 
        'MouseUp event and have it execute the Sub Window_Mouseup
        AddHandler Me.MouseUp, AddressOf Window_MouseUp
    End Sub

End Class

Now, the above is quite dangerous because you'll always be adding handlers any time the button is clicked. You should always be very careful about adding handlers - whenever you add one you MUST make sure to remove it before freeing up whatever has hooked it up (otherwise you end up with memory leaks since handlers can root an object!). I would always do something like this (in MainWindow) :

 Private _mouseUpConnected As Boolean = False

 Private Sub Page1_Clicked()
    If Not _mouseUpConnected Then
        AddHandler Me.MouseUp, AddressOf Window_MouseUp
        _mouseUpConnected = True
    End If
End Sub

This makes sure you only add the handler once. Now to get rid of it later :

Private Sub Window_Closed(sender As System.Object, e As System.EventArgs) _
                                                          Handles MyBase.Closed
    RemoveHandler Page1.PageButtonClick, AddressOf Page1_Clicked
    if _mouseupConnected then RemoveHandler Me.MouseUp, AddressOf Window_MouseUp
End Sub

This takes care of the PageButtonClick handler - it is added when the window is loaded and removed when it is closed. It also takes care of the MouseUp handler - if it has been connected, we disconnect it before closing. This ensures that MainWindow is properly garbage collected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top