- PR -

TabControl のページタイトル部の BackColor を変更したい。

投稿者投稿内容
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2007-10-30 10:26
引用:

uprushさんの書き込み (2007-10-28 18:46) より:

僕もこのページを参考して作りました。また、最後のところ、リソースの開放がいると思います。
コード:
    'リソース開放
    foreBrush.Dispose()
    backBrush.Dispose()
    e.Graphics.Dispose()




私の記憶が確かならば、foreBrush と backBrush は System.Brushes から取得したブラシを使っているわけで、それを解放してはいけないような気がします。
e.Graphics も同様に開放すべきではありません。

自分で作成した Brush なり Graphics なりであれば解放が必要ですが、これらは必要ないと思うのですが。
# 実際のところはそんなに詳しくないので、教えてえろいひと。

引用:

だんじりさんの書き込み (2007-10-30 09:46) より:

教えていただいたサイトを早速テストしていますが、次の2行がエラー(TabPagesは
DataGridView1.TabControlのメンバーではありません)になります。


???
DataGridView1.TabControlなのですか?
DataGridView1 って、DataGridView コントロールのことですよね?
そんなメンバーありましたっけ(それとも僕が知らないだけ?)。
DrawItem イベントはどのコントロールに設定してます?
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-30 10:56
ぽぴ王子(本物)さん、解答ありがとうございます。
リソース開放の件、了解しました。問題ないならこのままにします。
DataGridView1は、グリッドビューなど使っていないのに、私も不思議に思い、もう1つ
新しいフォームを作成し、同様な処理でエラーを調べましたが同じエラーが出ました。

DrawItem イベントは次の通りフォームのLoadで設定しました。
AddHandler TabC.DrawItem, AddressOf TabC_DrawItem '--DrawItemイベントハンドラ
(※TabCはTabControlの名前です)
以上、よろしくお願いいたします。

[ メッセージ編集済み 編集者: だんじり 編集日時 2007-10-30 11:02 ]
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-10-30 11:54
引用:

TabPagesはDataGridView1.TabControlのメンバーではありません。
Dim tab As TabControl = CType(sender, TabControl)'--対象のTabControlを取得



senderがDataGridView1に置き換わってメッセージされてますので
そもそもDataGridViewのイベントを拾ってるんじゃないですか?

あと、「解放」と「開放」の使い分けを。
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-30 13:00
まどかさん、ありがとうございました。
ご指摘の「senderがDataGridView1に置き換わってメッセージされてますので 」とのこ
とですが、私にはその意味が分りかねます。恐れ入りますがもう少しレベルダウンして
教えていただけないでしょうか。
よろしくお願いいたします。


だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-30 13:59
皆さん、すみません。
念のためにと、もう一度新たなフォームにTabControlを設置してオーナードローを掛け
たところ、全て正常に動作できました。ありがとうございました。
オーナードローは、色々やってみて最も効果的なのがこのTabControlだと思いました。
ListBoxにはあまり必要性を感じませんし、Buttonには画像を貼りつけるほうが手間がか
かりません。
早速スニペットのコントロールにも設定しました。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-10-30 14:46
引用:

だんじりさんの書き込み (2007-10-30 13:00) より:

ご指摘の「senderがDataGridView1に置き換わってメッセージされてますので 」とのことですが、私にはその意味が分りかねます。恐れ入りますがもう少しレベルダウンして教えていただけないでしょうか。


sender が別のコントロールに置き換わっているということはイベント ハンドラがあなたの思うとおりに設定されていないということになります。 たとえば、イベント プロシージャのシグネチャが TabControl_DrawItem(...) となっていても、違うハンドルと紐づいていれば、名前とは裏腹にまったく別のイベントが発生することになります。 ただ、

引用:

DrawItem イベントは次の通りフォームのLoadで設定しました。
AddHandler TabC.DrawItem, AddressOf TabC_DrawItem '--DrawItemイベントハンドラ
(※TabCはTabControlの名前です)


なら問題ないハズなので謎ですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-30 15:43
じゃんぬねっとさん、いつもありがとうございます。
1つ前のスレッドにも書きましたが、じゃんぬねっとさんの言われるとおり謎めいた話なので、3度目の新たなフォームをつくり再度実験してみますと、正常に動作しました。

じゃんぬねっとさんに教えていただいた「どぼんねっと」さんの.NET Tipsを再度
紹介しておきます。ありがとうございました。
http://dobon.net/vb/dotnet/control/tabownerdraw.html [dobon.net]

TabControlを使用する場合はぜひ使うべきと思いました。
私はTabの色設定を画面の調和を取るために次のようにしました。参考までに・・・

If e.State = DrawItemState.Selected Then
foreBrush = Brushes.White '---選択されているタブのテキストは白、
backBrush = Brushes.RoyalBlue '--背景をタイトル系の青
Else
foreBrush = Brushes.Black '--選択されていないタブのテキストは黒、
backBrush = Brushes.LightGray '--背景をライトグレー
End If



Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-30 21:28
引用:

だんじりさんの書き込み (2007-10-30 10:56) より:
ぽぴ王子(本物)さん、解答ありがとうございます。
リソース開放の件、了解しました。問題ないならこのままにします。


 いや、誰かが言ったからそうする、ではなく、なぜ要らないのか、理解して下さい。
結論として、ここでは解放する必要はありません。
問題ないのではなく、ここでは解放してはいけません。

 この結論よりも、結論に至った理由の方が重要です。
結論は、このケースにしか適用できないからです。
理由は、あらゆるケースに応用できます。

 uprushさんがおっしゃるように、Brush や Graphics は、IDispose インターフェイスを実装していますので、使い終わったら Dispose する必要があります。
問題は、「何時使い終わったか」ということです。

 この点で、ぽぴ王子様の記憶は確かです。
引用:

TabControlのタブを自分で描画する(DOBON.NET)より:
コード:
'TabControl1のDrawItemイベントハンドラ
Private Sub TabControl1_DrawItem( _
        ByVal sender As Object, ByVal e As DrawItemEventArgs)
    '対象のTabControlを取得
    Dim tab As TabControl = CType(sender, TabControl)
    'タブページのテキストを取得
    Dim txt As String = tab.TabPages(e.Index).Text

    'タブのテキストと背景を描画するためのブラシを決定する
    Dim foreBrush, backBrush As Brush
    If e.State = DrawItemState.Selected Then
        '選択されているタブのテキストを赤、背景を青とする
        foreBrush = Brushes.Red
        backBrush = Brushes.Blue
    Else
        '選択されていないタブのテキストは灰色、背景を白とする
        foreBrush = Brushes.Gray
        backBrush = Brushes.White
    End If

    'StringFormatを作成
    Dim sf As New StringFormat
    '中央に表示する
    sf.Alignment = StringAlignment.Center
    sf.LineAlignment = StringAlignment.Center

    '背景の描画
    e.Graphics.FillRectangle(backBrush, e.Bounds)
    'Textの描画
    Dim rectf As New RectangleF( _
        e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)
    e.Graphics.DrawString(txt, e.Font, foreBrush, rectf, sf)
End Sub




 ここで、foreBrush と backBrush は、Brushes に用意されているブラシを参照するようになっています。
ですから、ここで使用期間を気にしなければならないのは、Brushes に用意されているブラシがいつまで使われるか、というところです。
最初にこのメソッドが実行された後、二度とこのメソッドが実行されないなら、何らかの不都合が発生する可能性は低いでしょう。
しかし、複数回このイベント ハンドラが実行されると、二回目に入ってきた時には、解放済みのブラシを参照することになってしまいます。
これは、不都合を発生させないでしょうか?
(実際には、解放しようとしたときに例外が発生したと思います)

 次に e.Graphics です。
このメソッドの最後で解放した後、e.Graphics が参照している Graphics が使われるようなことがあると、そこで不都合が発生します。
ここでは「描くべきものをメモリに書いている」わけですが、そのメモリを表示用のメモリに転送する処理は、何時行われるのでしょう?
(これも例外が発生したと思います)

スキルアップ/キャリアアップ(JOB@IT)