3

我扩展了 TabControl 以支持单个选项卡的关闭按钮。看这个截图:

在此处输入图像描述

问题 1

将鼠标悬停在关闭按钮上不会立即触发按钮的 MouseHover 事件。大约 200 毫秒的小延迟导致悬停状态的图像显示延迟。如果我将鼠标悬停在按钮上的速度足够快,则该事件根本不会触发。

我使用以下代码将按钮放在 TabControl 上(使 Button 成为 TabControl 的子项):

[DllImport("User32", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);

...

SetParent(closeButton.Handle, this.Handle);

顺便说一句,这是不可能的:

closeButton.Parent = this; // this == instance of TabControl

它会导致异常,这就是我使用 API 调用的原因。

知道为什么 MouseHover 会延迟吗?

问题 2

关闭按钮不能使用具有透明背景的图像,因为背景将显示为系统控制颜色。我确实读过BackColor设置为透明的控件将采用父控件的BackColor。我的父控件是没有 BackColor 属性的 TabControl 实例。

有没有办法将 TabControl 的 BackColor 动态设置为透明?也许用winapi调用?

问题 3

正如您在屏幕截图中看到的那样,选项卡文本上缺少填充,导致关闭按钮覆盖文本。如何在不使用诸如在文本中添加一些空格之类的肮脏技巧的情况下解决此问题?

要获取选项卡标题项的位置,我使用 winapi 调用:

WinApi.RECT myRect = new WinApi.RECT();
WinApi.SendMessage(this.Handle, WinApi.TCM_GETITEMRECT, (IntPtr)this.TabPages.IndexOf(tab), ref myRect);
Rectangle realRect = new Rectangle(myRect.Left, myRect.Top, myRect.Width, myRect.Height);

也许有一种方法可以通过 api 调用来设置大小?可以设置 TCM_SETMINTABWIDTH,但这会更改所有选项卡的最小宽度。

问题 4

要定义哪个选项卡是可关闭的,我目前使用自定义方法:

ExtendedTabControl.SetTabCloseable(TabPage tab)

实现需要如何才能在 DesignMode 中工作?扩展 TabPage 类(添加属性“Closeable”),然后通知 VisualStudio(通过注释?)我的自定义 TabPage 类应该在 DesignMode 中使用?

4

2 回答 2

2

问题 1 假装是一个按钮可能比实际上是一个按钮要容易得多。将选项卡控件的 DrawMode 设置为 OwnerDrawFixed 并使用 DrawItem 事件绘制文本,然后绘制按钮。由于您已经完全控制了绘图,因此您可以剪切文本绘图并绘制透明图像等。

要模拟按钮,您需要处理 TabControl 的 MouseDown/MouseMove/MouseUp 事件

由于您没有任何实际按钮,因此您需要维护一个矩形列表,这些矩形是您绘制的按钮的边界。在鼠标事件中,你可以测试你是否在一个按钮上并采取相应的行动。

我的结果(用 Delphi 编写,所以它的代码对你没有太大帮助)最终看起来像这样: 带有关闭按钮的选项卡控件

按钮的图像最终通过绘制事件中的调用由窗口绘制。

问题 2 当您不使用真正的按钮时,这会消失。

问题 3 我知道的唯一方法是使用选项卡控件的 ItemSize 属性使选项卡足够宽以容纳文本。

问题 4 这成为选项卡本身的布尔属性,所以是的。如果您希望每个选项卡独立完成,则需要处理自己的选项卡页。这本身就是一个话题,因此对于另一个问题可能是最好的,而不是将其全部归为一个问题。

于 2013-02-01T12:50:06.500 回答
1
protected override void OnHandleCreated(EventArgs e) {
  SendMessage(NativeMethods.TCM_SETPADDING, 0, 
              NativeMethods.Util.MAKELPARAM(padding.X, padding.Y));
}
于 2015-02-10T02:37:51.787 回答