2013-02-01 34 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