WPF 类似组合框的自定义控件

发布于 2024-10-17 19:43:39 字数 801 浏览 3 评论 0原文

我想创建看起来像标准 WPF ComboBox 的自定义控件,但弹出窗口中不会有 ItemsPresenter,而是会出现另一个自定义控件。因此,我创建了一个派生自 System.Windows.Controls.Control 的新类,添加了 IsDropDownOpen 属性并创建了一个实际上是默认 副本的样式ComboBox 样式(主要思想是将 Popup.IsOpenToggleButton.IsPressed 属性绑定到控件的 IsDropDownOpen 属性)。

问题是当我单击控件外部时,Popup 没有关闭。

我查看了 Reflector 中的 ComboBox 类,发现 ComboBox 在失去鼠标捕获时使用了一些逻辑来更新 IsDropDownOpen 属性。但该代码使用了一些内部类。是否有其他方法可以确定用户是否在控件外部单击并关闭 Popup

UPD:我找不到附加文件进行发布的方法,因此我在此处上传了示例项目

有一个看起来像 ComboBox 的自定义控件,但它在弹出窗口中有一个 TreeView。当您打开弹出窗口并单击控件外部时,它会自动关闭,但如果您打开弹出窗口,展开“Item2”,然后单击外部,则弹出窗口不会关闭。问题是如何解决这个问题?

I would like to create custom control that will look like standard WPF ComboBox, but instead of instead of having an ItemsPresenter in the popup there will be another custom control. So, I created a new class that derives from System.Windows.Controls.Control, added a IsDropDownOpen property and created a style that is actually a copy of default ComboBox style (main idea is that the Popup.IsOpen and ToggleButton.IsPressed properties are bound to the IsDropDownOpen property of the control).

The problem is that the Popup is not closed when I click outside of the control.

I took a look at the ComboBox class in the Reflector and found out that ComboBox used some logic to update the IsDropDownOpen property when it loses mouse capture. But that code uses some internal classes. Is there any alternative way to determine if the user clicked outside of the control and close the Popup?

UPD: I didn't find the way to attach a file to post, so I uploaded sample project here

There is a custom control that looks like ComboBox, but it has a TreeView in a popup. When you open popup and click outside of the control it closes automatically, but if you open popup, expand 'Item2' and then click outside the popup isn't closed. The question is how to fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

将军与妓 2024-10-24 19:43:39

Control.LostFocus 事件,也许对此进行处理就足够了。

There is the Control.LostFocus event, maybe handling that would be sufficient for this.

忱杏 2024-10-24 19:43:39

这段代码解决了这个问题。

在静态构造函数中:

EventManager.RegisterClassHandler(typeof(CustomComboBox), Mouse.LostMouseCaptureEvent, new MouseEventHandler(OnMouseCaptureLost));

事件处理程序实现:

private void OnMouseCaptureLost(object sender, MouseEventArgs e)
{
   if (Mouse.Captured != _container)
   {
      if (e.OriginalSource != _container)
      {
         Mouse.Capture(_container, CaptureMode.SubTree);
         e.Handled = true; 
      }
   }
}

This code solves the problem.

In the static contructor:

EventManager.RegisterClassHandler(typeof(CustomComboBox), Mouse.LostMouseCaptureEvent, new MouseEventHandler(OnMouseCaptureLost));

Event handler implementation:

private void OnMouseCaptureLost(object sender, MouseEventArgs e)
{
   if (Mouse.Captured != _container)
   {
      if (e.OriginalSource != _container)
      {
         Mouse.Capture(_container, CaptureMode.SubTree);
         e.Handled = true; 
      }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文