DOBON.NET DOBON.NETプログラミング掲示板過去ログ

タブコントロールのタブについて

環境/言語:[XP/C#]
分類:[.NET]

皆さんはじめまして。

C#でカスタムコントロールを作成していて、
わからないことが発生してしまったため、掲示板に書き込ませて頂きます。

現在作成しているのは、タブコントロールです。
基底クラス”TabControl”から以下の点を変更したいと思っています。

・タブの表示位置を変更したい

.NET Tips「TabControlのタブを自分で描画する」を読んで、
DrawItemイベントに自作した描画用メソッドを追加して、
タブのデザインを自由に変更できることは理解しています。

わからない部分は、
DrawItemイベント発生以前に基底クラスで
描画しているタブについてです。

この基底クラスで描画しているタブの描画位置を
自分で設定できないのか?と悩んでいます。

よろしくお願い致します。
> ・タブの表示位置を変更したい

 TabControl.Alignment プロパティの設定では対処できない内容なのでしょうか? もしそうでしたら、完全自作の道を進むことになるような気がします。
早速の返信、ありがとうございます。

>  TabControl.Alignment プロパティの設定では対処できない内容なのでしょうか? もしそうでしたら、完全自作の道を進むことになるような気がします。

TabControl.Alignmentプロパティも試してみましたが、
期待通りの結果ではなかった気がします。

明日もう一度確認して、結果を書き込みます。


よろしくお願い致します。
#再確認頂けるとのことですけど、その前に少し

> TabControl.Alignmentプロパティも試してみましたが、
> 期待通りの結果ではなかった気がします。

 どのような結果を期待なさって、それとどう異なっていたのでしょうか?

 TabAlignment.Left ( もしくは TabAlignment.Right ) にしたとき、文字表示を縦書きにしたいということでしたら以下が参考になるでしょうけど‥‥

.NETプログラミング研究 第51号
・タブのテキストを縦書きにするには?
http://backno.mag2.com/reader/BackBody?id=200502090600000000104516000

 既にチェックされてるような気もしまし、もっと別のことなのでしょうね(^_^;)
 ともあれ、具体的なイメージをご提示されたほうが適切なアドバイスを受け易いと思いますよ。
<To:深山 さん>
TabControl.Alignmentプロパティを再度試してみましたが、
だめでした。

<To:All>
私が実現したいことに関して、
もう少し詳細に書いておきますね。

私が作成したいタブコントロールは、
TabControl.Apperanceプロパティを"Buttons"に設定し、
タブがボタン状に表示されるものを想定しています。

このボタン状のタブを表示してみた所、
以下の点が問題となったのです。

・タブ同士の間隔が狭い。
・一番左のタブ(最初のタブ)とタブコントロールの左端との間隔が狭い。

上記2点の問題を解決するためには、
やはり完全自作しかないのでしょうか?

皆さんの意見をお聞かせ下さい。
おろしくお願いします。
> ・タブ同士の間隔が狭い。
> ・一番左のタブ(最初のタブ)とタブコントロールの左端との間隔が狭い。

 仰られている『間隔』のイメージが今一つ解らないのですが‥‥
 通常図1のようになっているのを、図2のようにしたいという解釈でよろしいでしょうか?
違っているようでしたら以下は流してくださいませ。
#『タブ』はボタン表示になってるイメージ

( 図1 )
┌───┐┌───┐┌───┐
│タブ1││タブ2││タブ3│
└───┘└───┘└───┘──────────────┐
│                            │

( 図2 )
 ┌───┐ ┌───┐ ┌───┐
 │タブ1│ │タブ2│ │タブ3│
┌└───┘─└───┘─└───┘───────────┐
│                            │



 こういった内容の要望を挙げられた場合、私なら以下のいずれかで対応します。

・見た目だけの問題?
  → 我慢してもらう
・ボタンが小さくて扱い辛い?
  → ( タブ同士の間隔ではなく ) Padding プロパティ ないし ItemSize プロパティ の値を
   調整して図3を提示してみる

( 図3 )
┌─────┐┌─────┐┌─────┐
│ タブ1 ││ タブ2 ││ タブ3 │
└─────┘└─────┘└─────┘────────┐
│                            │

・図2のように間隔が空いていなければならない必然がある?
  → TabContol の使用は諦めて Button と Panel を配置して実装する
・ TabControl の機能をそのまま使用しなければ生産性が著しく低下する要因がある?
  → 図3と同様の設定をした上で小さめのボタンをオーナードロー。
   WM_NCHITTEST メッセージを監視し、ボタン描画されていない部分のクリックは無効とする。
   という内容で対処できないか模索してみる

 この要件に掛けられる工数との兼ね合いもありますけど、二つ目か三つ目の案でやることなるでしょう。
#‥‥って、全然参考にならない内容ですよね(汗)<回答になってないし
  • 題名: Re[5]: アドバイスありがとうございます
  • 著者: ゆう
  • 日時: 2005/05/20 16:35:58
  • ID: 10886
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
>  仰られている『間隔』のイメージが今一つ解らないのですが‥‥
>  通常図1のようになっているのを、図2のようにしたいという解釈でよろしいでしょうか?
> 違っているようでしたら以下は流してくださいませ。
> #『タブ』はボタン表示になってるイメージ
>
> ( 図1 )
> ┌───┐┌───┐┌───┐
> │タブ1││タブ2││タブ3│
> └───┘└───┘└───┘──────────────┐
> │                            │
>
> ( 図2 )
>  ┌───┐ ┌───┐ ┌───┐
>  │タブ1│ │タブ2│ │タブ3│
> ┌└───┘─└───┘─└───┘───────────┐
> │                            │
>
>
まさにその通りです。
本来ならば、上記のような図は
手前で作成しなければならない所。
ありがとうございます。

作成する上での問題ですが、
TabControl の機能をそのままに
見た目も実現する必要があります。

<2つ目の案について>
>  → TabContol の使用は諦めて Button と Panel を配置して実装する

実はこの方法は既に実装です。
情報が足りなくて申し訳ありませんでした。

<3つ目の案について>
> → 図3と同様の設定をした上で小さめのボタンをオーナードロー。
>   WM_NCHITTEST メッセージを監視し、ボタン描画されていない部分の
> クリックは無効とする。

この方法は有効であると思います。
実際に作成してみて、結果を書き込みます。

よろしくお願い致します。

PS
>#‥‥って、全然参考にならない内容ですよね(汗)<回答になってないし
とても参考になってます。
レスも早くてとても助かります。
3つ目の案で作成してみた結果、
以下の図のようになりました。

(図)
アスタリスク(*)で囲まれている四角は、
ItemSizeプロパティを調整して大きくしたタブです。

┌────┐
│  タブ1 │・・・オーナードローした小さ目のタブです。
└────┘

**************************************
* ┌────┐*┌────┐*┌────┐*
* │ タブ1  │*│ タブ2  │*│ タブ3  │*
* └────┘*└────┘*└────┘*
**************************************────┐
│                                   │
│                                   │
│                                   │


上記の図はほぼ要求通りでしたが、
以下一点のみ問題がありました。

・タブ(ボタン)を選択した時のデザイン
  TabControlクラスの機能として、選択されたタブ(ボタン)が凹み、
  さらにタブのリージョン(図のアスタリスク)が点線で示されます。
    →タブを選択した際に、オーナードローしたタブ(内側タブ)の周り(外側タブ)が凹んでしまう。

【結論】
   深山さんにアドバイスを頂き、いくつか作成した結果、
  タブを自分で作成(描画)できないことがネックになっていると考えています。

【解決策】
  ・TabControlクラスでタブを描画しているメソッドをオーバーライドする。

  あくまで予想ですが、TabControlクラスには各タブを作成
  (描画→リージョン設定)しているメソッドが存在するはずです。
  
  よって、このメソッドをオーバーライドしてやれば
  自由にタブを作成できるものと考えています。

【お願い】
  上記のタブ作成メソッドについて、
  何か情報(メソッド名や存在の有無etc)をお持ちでしたら教えて下さい。

  ※ 現在は逆アセンブルツールを使用して、
    タブ作成メソッドを探していますが、まだ発見できていません。
>   TabControlクラスの機能として、選択されたタブ(ボタン)が凹み、
>   さらにタブのリージョン(図のアスタリスク)が点線で示されます。
>     →タブを選択した際に、オーナードローしたタブ(内側タブ)の周り(外側タブ)が凹んでしまう。

 一工夫要りそう ( =面倒そう ) だったので「模索してみる」に留めてたのですけど、茨の道を進まれたのですね(^_^;)
#誤解されてるような気がするので念のために繰り返しておくと、私ならこの”四つ目の”案は採用しなかったでしょう。「我慢してもらう」は真面目な話、真っ先に提案する解決方法です。他の案で済むならそれに越したことはないだろうと思っておりました。
#でも考えてみたら、わざわざ掲示板で質問するくらいですもの、やらざるを得ない状況だったんですよね。きっと(汗)


>   あくまで予想ですが、TabControlクラスには各タブを作成
>   (描画→リージョン設定)しているメソッドが存在するはずです。

 私も詳しいわけではないですけど、この描画は OS が行っているのではないでしょうか。探しても見つからないような気がします。

 因みに私が頭に浮かべていたのは、以前やった内容↓を応用するというものでした。元のタブの枠が残ってしまうようなら、一部だけ DrawImage すればなんとかなるかな、と。

カレンダーに休日表示したい
http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=10378&rev=&no=0


 その後実際に少し試してみましたところ、−矢印ボタン ( 全てのタブが表示し切れていないときに表示されるもの ) との兼ね合いで、当初の思惑通りにはいかない部分もありましたけど−概ね問題ないようです。

 ただ、タブボタンが TabPage 表示部分と離れてしまうのは矢張り見栄えが悪いですね。
 気になるようでしたら

  ・タブの描画位置を上にずらす ( DrawImage の dest を調整 )
  ・ DisplayRectangle プロパティをオーバーライドする※

ことで対処できそうですので、試してみてください。

※良い方法がないか探してるときに見かけたものです。参考になるかと。
http://www.techheadbrothers.com/DesktopDefault.aspx?tabindex=1&tabid=7&AId=97



(余談)
 質問なさるときは実現したい内容の他にも
  ・現状どうなっているか
  ・何故そうしたいのか
が書き添えてあると有難いです。二度手間になるのが悲しいというのもありますけど、動機付けがはっきりしていれば別の方法を提案できることもありますので。

 それからこれは個人的な興味なのですが‥‥
 何故こういった機能を必要とされているのでしょう? 差し支えなければ教えて頂けると嬉しいです。
結果から申し上げますと、
TabControlクラスでタブを描画しているメソッドは発見できませんでした。
やはり茨の道は険しかったです(ToT)


>  それからこれは個人的な興味なのですが‥‥
>  何故こういった機能を必要とされているのでしょう? 差し支えなければ教えて頂けると嬉しいです。

今回、こういったタブの機能が必要となったのは、
提示されたデザインの実現性を調査していたことが背景にあります。
調査した結果、まず深山さんの第2案で実装可能であることが判明しました。
しかし、第2案でカスタマイズした
◆Buttonコントロールをクリック時に、対応したPanelを表示する
機能はタブコントロールそのものだ。という事でTabContorlでの実現性を調査していたのです。

ですので、後はNo10890で教えていただいたURLを参考にもう少し調査してみて終了とします。
#多分第4案はあまり深追いせずに、第2案で実装すると思います。

#普通は第2案で作成するようですね。発見したサンプルソースの中で一番イメージに近いものも第2案のようでした。
【サンプル】http://www.thecodeproject.com/cs/miscctrl/TabHeader.asp

>
> (余談)
>  質問なさるときは実現したい内容の他にも
>   ・現状どうなっているか
>   ・何故そうしたいのか
> が書き添えてあると有難いです。二度手間になるのが悲しいというのもありますけど、動機付けがはっきりしていれば別の方法を提案できることもありますので。
>
ご指摘ありがとうございます。
これからはこの点に注意して書き込みます。


多大なる協力をして頂いた深山さん
本当にありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板