basyura's blog

あしたになったらほんきだす。

WPF - 独自コントロールに独自イベント

某システムで xsl を用いた時に「xsl 地獄もう嫌だ」と心の底から思ったし、もろもろ設定の xml もうんざりだと思ってたのにココにきての xaml。これは最強の xml 地獄だなと思いつつ数年経過。ようやく書けるようになってきたかなという感じはするけど奥が深すぎて Microsoft なのに Google 検索が欠かせないとか闇が深すぎる。学習コストが高すぎる割に得られるものは・・・なら windows form の固定レイアウトでいいやって思っちゃうよねそりゃ。MVVM 便利なんだけど、便利って思える前に 98% ぐらい挫折しそう。割りとまじで。仕事で追い込まれてやるならまだしも趣味の領域で継続できるかはかなり疑問。みんなどこでノウハウを仕入れてくるんだ (切実)。

閑話休題

やりたいこと → 独自コントロールでオレオレイベントを発火させたい。


やってみた。

概要

  • 発生イベントの EventArgs を書き換える
  • UserControl で独自のイベントを定義する
  • MainWindow に SampleControl を埋め込んで SampleControl のクリックでイベントを受け取る

構成

MainWindow
└── SampleControl
      ├── SampleEventArgs
      └── SampleMouseEventArgs

MainWindow

  • SwitchEvent ボタンをクリックすると SampleMouseEventArgs イベントで通知される
  • RaiseSampleEvent ボタンをクリックすると SampleChanged イベントが発生する
<my:SampleControl
                  MouseLeftButtonDown="SampleControl_MouseLeftButtonDown"
                  SampleChanged="SampleControl_SampleChanged"
                  />

SampleControl

  • クリックイベントを書き換える
<Button Grid.Row="0" Content="SwitchEvent"      Click="SwitchEvent" />
<Button Grid.Row="1" Content="RaiseSampleEvent" Click="RaiseSampleEvent" Margin="0 10 0 0" />
public partial class SampleControl : UserControl
{
    /// <summary></summary>
    public static RoutedEvent SampleChangedEvent = EventManager.RegisterRoutedEvent(
                                                "SampleChanged", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(SampleControl));
    /// <summary>
    ///
    /// </summary>
    public SampleControl()
    {
        InitializeComponent();
    }
    /// <summary>
    ///
    /// </summary>
    public event RoutedEventHandler SampleChanged
    {
        add    { AddHandler(SampleChangedEvent,    value); }
        remove { RemoveHandler(SampleChangedEvent, value); }
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SwitchEvent(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
        RaiseEvent(new SampleMouseEventArgs(Mouse.PrimaryDevice , 0, MouseButton.Left)
        {
            RoutedEvent = SampleControl.MouseLeftButtonDownEvent,
            Source      = this,
        });
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void RaiseSampleEvent(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
        RaiseEvent(new SampleEventArgs(SampleControl.SampleChangedEvent));
    }
}

イベントの書き換えはやっていいものなのか?という疑問はあるけど。