羽叶 发表于 2022-12-29 14:44:22

DirectX窗体标题栏中的元素点击事件不能正确触发的解决方法

大家知道,在DevExpress的DirectXForm中我们可以自定义窗体样式,包括系统按钮和自定义工具栏。
其中有三个特定的按钮为系统窗体自带的“最小化”、“最大化/还原”、“关闭”的功能按钮。这三个按钮无需手动处理点击事件,只需将按钮的id设置为“minimizebutton”、“maximizebutton”或“closebutton” 就能实现对应的功能。
对于系统标题栏中的其它按钮点击事件我们需要手动处理。
<div class="shadowframe">
      <div class="frame" id="frame">
                <div class="titlebar">
                        <div class="form-caption">DirectX窗体</div>
                        <div class="form-sysbtns">
                              <img class="sysbtns" src="SystemButtonMenu" id="sbar_menubutton"/><!-- 自定义菜单按钮 -->
                              <img class="sysbtns" src="SystemButtonMinimize" id="minimizebutton"/><!-- 最小化系统按钮 -->
                              <img class="sysbtns" src="SystemButtonMaximize" id="maximizebutton"/><!-- 最大化/还原系统按钮 -->
                              <img class="sysbtns" src="SystemButtonClose" id="closebutton"/><!-- 关闭系统按钮 -->
                        </div>
                </div>
                <div class="content" id="content">
                        <!--<div class="contenttext">Application Content</div>-->
                </div>
      </div>
</div>
this.HtmlElementMouseClick += (sender, e) => {
    switch (e.ElementId)
    {
      case "sbar_menubutton":
      //do something
      break;
    }
};
需要注意的是,其它部位的元素点击事件这样处理就可以了,但是窗体标题栏上的元素会出现不能正确触发点击事件的情况(有时候快速双击可以触发点击事件)。发生这种情况的原因是因为窗体的标题栏会截获所有鼠标事件,当指针位于标题栏上并且按下鼠标按钮时,程序默认将此操作视为窗体拖动操作的开始,所以如果需要使标题栏元素具有互交性我们需要在HtmlElementMouseDown事件中将MouseArgs.Handled 设置为 true,代码如下:
this.HtmlElementMouseDown += (sender, e) => {
    var args = e.MouseArgs as DXMouseEventArgs;
    if (e.ElementId.StartsWith("sbar_"))
      args.Handled = true;
};

这样就可以将所有名称以"sbar_"开头的按钮点击视为已处理操作,也就不会出现系统拦截的情况了。
页: [1]
查看完整版本: DirectX窗体标题栏中的元素点击事件不能正确触发的解决方法