以编程方式将事件处理程序附加到自定义子元素路由事件

时间:2021-03-05 21:19:14

标签: wpf user-controls routed-events

我有一个带有按钮和弹出窗口的窗口。单击按钮时,后面代码中的事件处理程序会打开 Popup。在单击时我有按钮的弹出窗口上,后面的代码中的事件处理程序关闭弹出窗口。简单的。原油。

我还有一个 UserControl,它有一个自定义路由事件和一个引发该事件的 Button。 该 UserControl 已放置在弹出窗口中。

我已在 XAML 中为 UserControl 自定义事件在 Popup 元素上添加了一个事件处理程序。在后面的代码中,我显示了一个消息框。

这一切都很好,很花哨。

这是一个极其简化的例子。我的最终问题是,如何以编程方式将事件处理程序附加到 Popup 级别的自定义路由事件?

用户控件 XAML:

  <Grid>
    <Button
      Width="100"
      Height="100"
      Click="Button_Click"
      Content="Event!" />
  </Grid>

背后的 UserControl 代码:

    public static readonly RoutedEvent CustomEventEvent = EventManager.RegisterRoutedEvent(
      nameof(CustomEvent), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl1));

    public event RoutedEventHandler CustomEvent
    {
      add => this.AddHandler(CustomEventEvent, value);
      remove => this.RemoveHandler(CustomEventEvent, value);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      RaiseEvent(new RoutedEventArgs(CustomEventEvent));
    }

主窗口 XAML:

  <Grid>

    <Button
      Width="200"
      Height="100"
      Click="Button_Click"
      Content="Popup" />

    <Popup
      x:Name="MyPopup"
      local:UserControl1.CustomEvent="MyPopup_CustomEvent"
      AllowsTransparency="True"
      Loaded="MyPopup_Loaded"
      Placement="Right">
      <Border
        Background="Azure"
        BorderBrush="Gray"
        BorderThickness="2"
        CornerRadius="3">
        <Grid Width="500" Height="300">
          <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
          </Grid.RowDefinitions>

          <Button
            Grid.Row="0"
            Width="100"
            Height="100"
            Click="Button_Click_1"
            Content="Close" />

          <local:UserControl1
            Grid.Row="1"
            Width="100"
            Height="100" />
        </Grid>
      </Border>
    </Popup>

  </Grid>

背后的主窗口代码(减去无聊的弹出打开/关闭按钮点击):

    private void MyPopup_CustomEvent(object sender, RoutedEventArgs e)
    {
      MessageBox.Show("YAY");
    }

    private void MyPopup_Loaded(object sender, RoutedEventArgs e)
    {
      if (sender is Popup popup)
      {
        // Here is where the wheels fall off.
        // How do I find/attach to the routed event after it has bubbled up to the popup?
        // popup.CustomEvent += LocalMyPopup_CustomEvent;
      }
    }

    private void LocalMyPopup_CustomEvent(object sender, RoutedEventArgs e)
    {
    }

最终,许多弹出窗口中将有几个的用户控件,我宁愿不必将事件处理程序附加到每个和他们中的每一个。特别是考虑到我可以使用 MyPopup_CustomEvent 在弹出级别获取它们。我只想复制这种行为。

1 个答案:

答案 0 :(得分:0)

事实证明,解决方案是微不足道的,但(事后看来)显而易见。 AddHandler 必须直接在 Popup 上调用并传入静态路由事件引用。

private void MyPopup_Loaded(object sender, RoutedEventArgs e)
{
  if (sender is Popup popup)
  {
    popup.AddHandler(UserControl1.CustomEventEvent, new RoutedEventHandler(LocalMyPopup_CustomEvent), true);
    // popup.CustomEvent += LocalMyPopup_CustomEvent;
  }
}
相关问题