3

個々のタブの閉じるボタンをサポートするために、TabControl を拡張しました。このスクリーンショットを参照してください。

ここに画像の説明を入力

問題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」を追加)、カスタム TabPage クラスを DesignMode で使用する必要があることを (注釈を介して) VisualStudio に通知しますか?

4

2 に答える 2

2

問題1 実際にボタンであるよりも、ボタンであるふりをする方がおそらくはるかに簡単です。タブコントロールのDrawModeをOwnerDrawFixedに設定し、DrawItemイベントを使用してテキストを描画してからボタンを描画します。描画を完全に制御したので、テキスト描画をクリップしたり、透明な画像を描画したりできます。

ボタンをエミュレートするには、TabControlのMouseDown / MouseMove/MouseUpイベントを処理する必要があります

実際のボタンはないので、描画したボタンの境界である長方形のリストを維持する必要があります。マウスイベントでは、ボタンを超えているかどうかをテストし、それに応じて行動することができます。

私の結果(Delphiで記述されているため、コードはそれほど役に立ちません)は、次のようになります。 閉じるボタン付きのタブコントロール

ボタンの画像は、ペイントイベントの呼び出しによって最終的にウィンドウによって描画されます。

問題2 これは、実際のボタンを使用しない場合に解消されます。

問題3 これについて私が知っている唯一の方法は、タブコントロールのItemSizeプロパティを使用して、テキストを取得するのに十分な幅のタブを作成することです。

問題4 これはタブ自体のブールプロパティになるので、そうです。これをタブごとに独立して実行する場合は、独自のタブページを処理する必要があります。これはそれ自体が少しトピックなので、すべてを1つにまとめるのではなく、別の質問に最適な場合があります。

于 2013-02-01T12:50:06.500 に答える