2013-02-01 31 views
3

我已经将TabControl扩展为支持单个选项卡的关闭按钮。看到这个截图:扩展.net的一些问题TabControl

enter image description here

问题1

悬停在关闭按钮不会立即触发按钮的MouseHover事件。有一个约200毫秒的小延迟,导致图像悬停状态显示延迟。如果我将鼠标悬停在按钮上,事件根本不会触发。

我用下面的代码放置该按钮到TabControl的(使按钮的的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中使用?

回答

2

问题1 假装是一个按钮比实际上是一个按钮要容易得多。 将选项卡控件的DrawMode设置为OwnerDrawFixed,并使用DrawItem事件绘制文本,然后使用按钮。既然你已经采取了绘图你可以剪辑的文字画,绘制透明图像的完全控制权等

要模仿你需要处理到的TabControl的

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

我的结果(Delphi编写的所以它的代码不会真正帮助你那么多)结束这样看: Tab control with close button

该按钮的图像最终被通过窗口在内线呼叫画事件。

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

问题3 我唯一知道的方法是使用tab控件的ItemSize属性使标签足够宽以接受文本。

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

+0

#1:问题是,用OwnerDrawFixed我会失去视觉风格。这不是一个选项。 #2:我想我必须手动绘制。尽管现在我对结果感到满意。 #3:仅适用于OwnerDrawFixed或固定的选项卡宽度,这不是选项。我申请了黑客(追加空格),工作正常。 #4:我猜到了。在我的尝试中,我发现它不可能是非常麻烦的。当前状态:http://imgur.com/jzZZtDC – user990827

+0

@ user990827您必须通过OwnerDraw丢失视觉样式,但确实触摸很复杂。有一些信息[这里](http://msdn.microsoft.com/en-gb/library/windows/desktop/dd373487(v = vs.85).aspx) –

+0

谢谢你看起来很有趣。虽然看起来很复杂。 – user990827

0
protected override void OnHandleCreated(EventArgs e) { 
    SendMessage(NativeMethods.TCM_SETPADDING, 0, 
       NativeMethods.Util.MAKELPARAM(padding.X, padding.Y)); 
} 
+3

除非添加所需的声明,否则这不会对用户有所帮助。解释代码的作用也会有所帮助。 – LarsTech