3

C#では、イベントは常に非常に保護されていました。イベントの所有者のみがイベントをトリガーできました。ただし、これはWPFでは完全に異なるようです。誰でもいつでも任意のイベントをスローできます。それをテストするために、私は下部にコードを書きました。

RaiseEventを使用してButton.Clickを発生させたとき、上記のイベントがそれをキャッチしました。それはWPFイベントの計画された動作ですか?誰かに彼らが望むイベントを投げさせるだけですか?また、そうであれば、イベントを登録するときのOwnerTypeの意味は何ですか?ある種の保護だと思いましたが、そうだとすれば、誰でも公開イベントにアクセスし、AddOwner関数を使用して所有者を追加できるため、不十分な保護です。

ありがとう!

XAML

<StackPanel Button.Click="ButtonBase_OnClick">
    <Button Name="RealButton">Real button</Button>
    <WpfWindow:VitalyControl MouseDown="UIElement_OnMouseDown">
      I am almost a button
    </WpfWindow:VitalyControl>
</StackPanel>

背後にあるコード

カスタムコントロール:

class VitalyControl : Label
{
    public VitalyControl()
    {
        this.MouseDown += new MouseButtonEventHandler(VitalyControl_MouseDown);
    }

    void VitalyControl_MouseDown(object sender, MouseButtonEventArgs e)
    {
        RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));
    }
}

そしてハンドラー:

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Button was pressed");
    }
4

1 に答える 1

3

これは仕様によるものであり、実際にはRoutedEventsの理由の1つです。これらは要素ツリー全体にルーティングされるため、ルーティングイベントと呼ばれます。発生している動作は、 msdnでは「単一ハンドラーアタッチメントポイント」と呼ばれます。StackPanelがすべてのButton.Clickイベントをリッスンするように指定します。

カスタムコントロールでは、ボタンクリックイベントを発生させます。この「バブル」は、それを処理するスタックパネルまで続きます。

アップデート:

このルーティングが機能するためには、すべてのUIElementがルーティングされたイベントを発生させることができる必要があると思います。ルーティングされたイベントはUI要素によってのみ使用され、WinForms実装の複雑さに対する答えです。これらはCLRイベントの代わりにはなりません。所有者タイプは、名前でイベントを解決するときに内部的に使用されます。

于 2011-02-03T18:09:27.923 に答える