0

私は立ち往生しています。ボタンをクリックするとイベントAddHandlerが発生するように Page1 のボタンを作成しようとしているので、MainWindow の任意の場所をクリックしてメッセージを表示できます。AddHandlerMainWindow_MouseUp

この問題を解決するにはどうすればよいですか?


ノート:

  • MaindWindow_load イベントの MainWindow_MouseUp のハンドラを削除したので、MainWindow のロード時にメッセージは表示されません。
  • Page1 を表示するフレームがあります。
  • Page1 のボタンがクリックされると、AddHandler になるはずなので、MainWindow が MainWindow_MouseUp イベントを実行すると、MainWindow_MouseUp はメッセージを表示します。

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
4

1 に答える 1

1

これは少し混乱しています。あなたがしていることを見てみましょう:

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

これは、新しい MainWindow を作成し、その MouseUp イベントをメソッドにリンクしています。イベントを発生させたときにのメソッドを実行するようにButton1_Click指示しています。これはあなたがやりたいことではないと思います。_MainWindowPage1Button1_ClickMouseUp

今これ:

RemoveHandler Me.MouseUp, AddressOf MainWindow_MouseUp

MainWindow_MouseUpすぐに夢中になりたくないと言います。Handles次のような句を削除するだけで、この行を削除できます。

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

これで、削除するものは何もありません。

というわけで... Page1 のボタンがクリックされたことを MainWindow に通知する問題に戻ります。これを行うには、イベントを 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

ここでイベントsharedを作成しました。これにより、MainWindow でページのインスタンスを作成せずにイベントをリンクできます (つまり、Page1 をソースとして使用するフレームを簡単に作成できます)。ここで行っているのはPageButtonClick、Button1 がクリックされたときに Page1 でイベントを発生させることです。

メインウィンドウで、次のようにします。

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

ボタンがクリックされるたびに常にハンドラーを追加することになるため、上記は非常に危険です。ハンドラーの追加には常に細心の注意を払う必要があります - ハンドラーを追加するときはいつでも、フックされているものを解放する前に必ず削除する必要があります (そうしないと、ハンドラーがオブジェクトをルート化できるため、メモリ リークが発生します!)。私はいつもこのようなことをします(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

これにより、ハンドラーを 1 回だけ追加するようになります。後でそれを取り除くために:

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

これは PageButtonClick ハンドラーを処理します。ウィンドウがロードされると追加され、ウィンドウが閉じられると削除されます。また、MouseUp ハンドラーも処理します。接続されている場合は、閉じる前に切断します。これにより、MainWindow が適切にガベージ コレクションされるようになります。

于 2013-06-10T23:11:04.027 に答える