【问题标题】:How to handle Click event on a custom WPF control composed of controls that don't have Click events如何处理由没有 Click 事件的控件组成的自定义 WPF 控件上的 Click 事件
【发布时间】:2016-10-29 13:43:12
【问题描述】:

我正在创建一个可以在我的 WPF 应用程序中使用的自定义 ToolBar 控件。

我的 CustomToolBar 控件基于 StackPanel 控件,将包含多个 CustomToolBarButton 控件。

我的 CustomToolBarButtons 基于垂直 StackPanel 并包含一个 Image 控件和一个 Label 控件。

我想以编程方式为我的 CustomToolBarButtons 创建一个 Click 事件,该事件将在单击 Image 或 label 时触发。不幸的是,Image 和 Label 控件在 WPF 中都没有 Click 事件。

这对我来说是一个惊喜,因为我习惯了 WinForms 控件,并且绝大多数默认情况下都有 Click 事件。我是否必须创建自定义图像和标签控件并为它们创建 Click 事件,或者是否有更清洁和更简单的方法来执行此操作?

感谢您的帮助!

【问题讨论】:

    标签: c# .net wpf custom-controls


    【解决方案1】:

    好吧,使用标准功能并没有一种既简单又好用的方法。我通过制作自己的触发器(源自 Blend SDK 的 System.Windows.Interactivity.TriggerBase)解决了这个问题,以便在我的项目中执行以下操作:

         <Label> 
             <i:Interaction.Triggers>
                 <mu:MouseTrigger MouseButton="Middle" MouseAction="Click">
                     <i:InvokeCommandAction Command="{Binding Path=Close}" />
                 </mu:MouseTrigger>
             </i:Interaction.Triggers>
         </Label>
    

    MouseTrigger 类将有效地处理来自UIElement 的 MouseDown 和 MouseUp 事件,并使用它来调用与触发器关联的操作。不过,代码比这要复杂一些,因为我还进行鼠标捕获并且我使用了一个内部帮助程序类,这样我就可以将多个触发器添加到同一个元素,而只有一个帮助程序类的实例处理事件并捕获该元素的鼠标。

    对于实际操作,我只使用现有的 Blend 或 Prism 操作,例如 InvokeCommandAction。

    如果您有兴趣,这里是the project。它太大,无法粘贴到这种格式中。它使用了一些 C# 6.0 功能,但您可以通过删除一些空条件运算符轻松修改它以在旧版本的 C# 上工作。它需要您安装 Blend SDK,因为它取决于 System.Windows.Interactivity(只要您选择该选项,就应该与 Visual Studio 一起安装)。 MouseTrigger 是公开可见的类,它是与功能交互的点。 MouseCatcher 是提到的内部帮助类。

    我建议不要沿用自定义控件的路线,而是使用某种机制(这种机制或其他机制)使用 WPF 和 XAML 带来的附加属性框架来扩展现有功能。

    【讨论】:

      【解决方案2】:

      在 WinForms 中,您将创建自定义控件只是为了获得非标准外观,而在 WPF 中,这不再是必需的。

      WPF 方式:不是让Stackpanel 的孩子实现Click 行为,而是让Button 看起来像所需的Stackpanel

      可以这样设置Content

      <Button>
          <StackPanel >
              <Image Source="C:\myFiles\myPic.png"/>
              <Label HorizontalAlignment="Center">SomeTxt</Label>
          </StackPanel>
      </Button> 
      

      但是这样它看起来仍然像Button,为了克服这个问题,我们可以设置Template

      <Button>
          <Button.Template>
              <ControlTemplate TargetType="Button">
                  <StackPanel >
                      <Image Source="C:\myFiles\myPic.png"/>
                      <Label HorizontalAlignment="Center">SomeTxt</Label>
                  </StackPanel>
              </ControlTemplate>
          </Button.Template>
      </Button>   
      

      两种解决方案都会引发单击图像或标签的 Click 事件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多