C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: Brushesのカラーコードを変数に出来ませんか?


(過去ログ 106 を表示中)

[トピック内 20 記事 (1 - 20 表示)]  << 0 >>

■63492 / inTopicNo.1)  Brushesのカラーコードを変数に出来ませんか?
  
□投稿者/ やんまー (3回)-(2012/09/01(Sat) 14:48:07)

分類:[VB.NET/VB2005 以降] 

畏れ入ります。

ListBoxの項目をオーナードローで色を付けようとしています。

その際
e.Graphics.FillRectangle(Brushes.Black, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))

のようにするわけですが、この”Black”の部分を変数に出来ないのでしょうか?

単純にColorであれば

Color.FromName(Name:="Black")
Color.FromName("Black")

のようにすれば良いと知っていたので


Brushes.FromName("Black")
Brushes.Color.FromName("Black")


とやってみたのですが、NGでした。。。


Brushes クラス
http://msdn.microsoft.com/ja-jp/library/system.drawing.brushes(v=vs.80).aspx



何かいい方法はないでしょうか?



引用返信 編集キー/
■63493 / inTopicNo.2)  Re[1]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ Azulean (26回)-(2012/09/01(Sat) 14:58:02)
SolidBrush クラスを使えばよいのでは?Color 構造体を渡せます。

// Dispose 忘れに注意。
引用返信 編集キー/
■63494 / inTopicNo.3)  Re[1]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ shu (54回)-(2012/09/01(Sat) 16:17:44)
No63492 (やんまー さん) に返信

本題についてはAzuleanさんの回答通りですが

> その際
> e.Graphics.FillRectangle(Brushes.Black, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))

RectangleFをこの表記で作成しなくても
CType(e.Bounds, RectangleF)
とすれば良いです。しかもこの呼び方の場合Rectangleも渡せるのでe.BoundsでOKです。
引用返信 編集キー/
■63495 / inTopicNo.4)  Re[2]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (4回)-(2012/09/02(Sun) 09:03:14)
Azulean さん

> SolidBrush クラスを使えばよいのでは?Color 構造体を渡せます。
>
> // Dispose 忘れに注意。


ありがとうございます。

Dim shadowBrush As SolidBrush = New SolidBrush(color.FromName("RED"))
e.Graphics.FillRectangle(shadowBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))

でいけました!

引用返信 編集キー/
■63496 / inTopicNo.5)  Re[2]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (5回)-(2012/09/02(Sun) 09:05:00)
shu さん
>
> 本題についてはAzuleanさんの回答通りですが
>
>>その際
>>e.Graphics.FillRectangle(Brushes.Black, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
>
> RectangleFをこの表記で作成しなくても
> CType(e.Bounds, RectangleF)
> とすれば良いです。しかもこの呼び方の場合Rectangleも渡せるのでe.BoundsでOKです。

おっしゃるとおり

e.Graphics.FillRectangle(shadowBrush, e.Bounds )

でいけました!

補足ありがとうございます!


引用返信 編集キー/
■63497 / inTopicNo.6)  Re[3]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ Azulean (27回)-(2012/09/02(Sun) 09:56:27)
No63495 (やんまー さん) に返信
>>// Dispose 忘れに注意。
(略)
> Dim shadowBrush As SolidBrush = New SolidBrush(color.FromName("RED"))
> e.Graphics.FillRectangle(shadowBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
>
> でいけました!

Brushes で得られる Brush は Dispose 不要ですが、自分で SolidBrush を作った場合は Dispose が必要です。
上記のコードでは Dispose が書かれていませんでしたが、きちんと書いていますか?
(Using を使うと楽かも)
引用返信 編集キー/
■63498 / inTopicNo.7)  Re[4]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (6回)-(2012/09/02(Sun) 10:00:31)
Azulean さん

>
> Brushes で得られる Brush は Dispose 不要ですが、自分で SolidBrush を作った場合は Dispose が必要です。
> 上記のコードでは Dispose が書かれていませんでしたが、きちんと書いていますか?
> (Using を使うと楽かも)


ご指摘ありがとうございます。

Dispose入れてあります!



引用返信 編集キー/
■63499 / inTopicNo.8)  Re[1]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (7回)-(2012/09/02(Sun) 10:11:22)
畏れ入ります。

上手く行った!と思ったのですが、
一つおもっていなかった点がありました。

Listboxにオーナードローで背景を描画すると、選択時に反転しなくなってしまうのですね・・・


そこでListBox1DrawItemでは、e.Indexにインデックス番号が入るので

If listBox1.SelectedIndex = e.Index Then
	shadowBrush = New SolidBrush(color.FromName("green"))
Else
	shadowBrush = New SolidBrush(color.FromName("red"))
End If


のようにしてみたのですが、選択し直した場合には
前回の選択部分がgreenになったままで、いまいちでした。


なにかもっとスマートなやり方はないでしょうか・・・?



引用返信 編集キー/
■63500 / inTopicNo.9)  Re[2]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ 魔界の仮面弁士 (44回)-(2012/09/02(Sun) 11:15:54)
No63499 (やんまー さん) に返信
> Listboxにオーナードローで背景を描画すると、選択時に反転しなくなってしまうのですね・・・

オーナードローは開発自身が描画するためのものです。
選択時(引数 e.State を見て、そこに DrawItemState.Selected が付与されていた場合)に
どのように表示させるかも、開発者自身で決めてください。

選択時に反転表示させたいなら、反転表示のための描画コードを記述する必要がありますし、
e.DrawFocusRectangle を呼び出すかどうかも、開発者の任意です。


ちなみに、e.DrawBackground() を呼び出すと、項目が選択されているかどうかに
あわせて、標準の背景色が描画されるようになっています。標準外の色で
描画したい場合には、前景色/背景色も自前で指定しましょう。
引用返信 編集キー/
■63504 / inTopicNo.10)  Re[2]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ shu (55回)-(2012/09/03(Mon) 07:53:31)
No63499 (やんまー さん) に返信

念のため
魔界の仮面弁士 さんの言う
> 引数 e.State を見て、そこに DrawItemState.Selected が付与されていた場合

(e.State And DrawItemState.Selected) > 0
であり
e.State = DrawItemState.Selected
としないように。


e.DrawFocusRectangle を使用する場合、この処理内で判断をしているのでe.Stateを
確認する必要はありません。

e.StateがComboBoxEditを含んでいる場合は、編集領域の描画となるので、編集領域とリスト領域の描画を
分けたい場合はチェックをして下さい。
引用返信 編集キー/
■63505 / inTopicNo.11)  Re[3]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (8回)-(2012/09/03(Mon) 10:51:47)
魔界の仮面弁士 さん

失礼しました。
単にe.DrawFocusRectangle()を呼び出していなかったからのようでした。

選択時に濃い紺色に反転するようになりました。

> ちなみに、e.DrawBackground() を呼び出すと、項目が選択されているかどうかに
> あわせて、標準の背景色が描画されるようになっています。標準外の色で
> 描画したい場合には、前景色/背景色も自前で指定しましょう。

すいません・・・
この部分がわかりませんでした。
この選択時の濃い紺色の色も変えられるということでしょうか・・?




> ■No63499 (やんまー さん) に返信
>>Listboxにオーナードローで背景を描画すると、選択時に反転しなくなってしまうのですね・・・
>
> オーナードローは開発自身が描画するためのものです。
> 選択時(引数 e.State を見て、そこに DrawItemState.Selected が付与されていた場合)に
> どのように表示させるかも、開発者自身で決めてください。
>
> 選択時に反転表示させたいなら、反転表示のための描画コードを記述する必要がありますし、
> e.DrawFocusRectangle を呼び出すかどうかも、開発者の任意です。
>
>
> ちなみに、e.DrawBackground() を呼び出すと、項目が選択されているかどうかに
> あわせて、標準の背景色が描画されるようになっています。標準外の色で
> 描画したい場合には、前景色/背景色も自前で指定しましょう。
引用返信 編集キー/
■63506 / inTopicNo.12)  Re[3]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ やんまー (9回)-(2012/09/03(Mon) 10:55:05)
shu さん

if CBool(e.State And DrawItemState.Selected) = False Then
e.Graphics.FillRectangle(shadowBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
End If

のようにしました!



> ■No63499 (やんまー さん) に返信
>
> 念のため
> 魔界の仮面弁士 さんの言う
>>引数 e.State を見て、そこに DrawItemState.Selected が付与されていた場合
> は
> (e.State And DrawItemState.Selected) > 0
> であり
> e.State = DrawItemState.Selected
> としないように。
>
>
> e.DrawFocusRectangle を使用する場合、この処理内で判断をしているのでe.Stateを
> 確認する必要はありません。
>
> e.StateがComboBoxEditを含んでいる場合は、編集領域の描画となるので、編集領域とリスト領域の描画を
> 分けたい場合はチェックをして下さい。
引用返信 編集キー/
■63507 / inTopicNo.13)  Re[4]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ shu (56回)-(2012/09/03(Mon) 12:36:30)
No63506 (やんまー さん) に返信
 
> if CBool(e.State And DrawItemState.Selected) = False Then
> 
> のようにしました!
> 
結果は同じになりますが
if (e.State And DrawItemState.Selected) = 0 Then
とした方がよいです。
CBoolで変換するときに互換性のために0をFalseに変換し
それ以外をTrueに変換はしていますが
Integer And Integer の値はIntegerであってBooleanではないので
このような意味が分かりにくい変換をすべきではないと思います。

引用返信 編集キー/
■63511 / inTopicNo.14)  Re[5]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ 魔界の仮面弁士 (45回)-(2012/09/03(Mon) 20:00:48)
# 本題とは別の所に反応

No63507 (shu さん) に返信
>>if CBool(e.State And DrawItemState.Selected) = False Then
> Integer And Integer の値はIntegerであってBooleanではないので
> このような意味が分かりにくい変換をすべきではないと思います。

Boolean ではないからこそ CBool しているのだと思いますよ。

それはさておき、VB でビットマスクを And した結果を CBool を使って判定する手法は、
公式サンプルでも見かけていたせいか、私は特に不自然さを感じませんでした。


[VBA/VB6]
http://msdn.microsoft.com/en-us/library/windows/desktop/ms676162(v=vs.85).aspx
》 If CBool(Cnxn.State And adStateExecuting) Then


[VBScript]
http://gallery.technet.microsoft.com/scriptcenter/6a8d547e-8836-41d9-9169-2833507b32a9
》 If CBool(userAccountControlOriginal And UF_TRUSTED_FOR_DELEGATION ) = False Then


[VB.NET]
http://msdn.microsoft.com/ja-jp/library/zf50za27%28v=vs.90%29.aspx
》 If CBool(styles And NumberStyles.AllowCurrencySymbol) Then



まぁ、MS のサンプルでも、「= 0」「CBool」等々の揺れはありますから、
> if (e.State And DrawItemState.Selected) = 0 Then
の表記でも、もちろん問題は無いと思いますけれどね。

あるいは、こういう表記方法もありますね。

http://msdn.microsoft.com/ja-jp/library/hds568h4(v=vs.80).aspx
》 If (MyAttr And FileAttribute.Directory) = FileAttribute.Directory Then

http://dobon.net/vb/dotnet/control/lbownerdraw.html
》 If (e.State And DrawItemState.Selected) <> DrawItemState.Selected Then


しかしその一方で、先の No63504
> (e.State And DrawItemState.Selected) > 0
という書き方は避けるようにしています。マスクが符号付の型である場合は特に。

確かに > 0 で判定されているサンプルもあるのですけど、
「= 0」の反対を「> 0」とすることに私は違和感を覚えるため、
整数比較を採用する場合は「(X And Mask) > 0」と書くのではなく、
代わりに「(X And Mask) <> 0」と書くようにしています。


これが .NET 4 なら、「HasFlag メソッドを使う」という案もありますが、
あれは引数が汎用の Enum 型なので、あまり好きでは無かったり。
引用返信 編集キー/
■63514 / inTopicNo.15)  Re[6]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ shu (58回)-(2012/09/03(Mon) 23:01:22)
No63511 (魔界の仮面弁士 さん) に返信

> >>if CBool(e.State And DrawItemState.Selected) = False Then
>>Integer And Integer の値はIntegerであってBooleanではないので
>>このような意味が分かりにくい変換をすべきではないと思います。
>
> Boolean ではないからこそ CBool しているのだと思いますよ。
>
> 〜 公式のサンプル 〜
>
CBoolはBoolean型への変換を行う関数であって
=0ならFalse
<>0ならTrue
にするというのが目的の関数ではないはず。たまたま互換性のため
そうしているがBooleanというのは真偽を表すための型であり全てのビットがoff、または
どれかのビットがonになっている状態を表すための型としての使い方は保障されるものでは
ない気がします。実質的には変更されることはないのでしょうけど。


> しかしその一方で、先の No63504
>>(e.State And DrawItemState.Selected) > 0
> という書き方は避けるようにしています。マスクが符号付の型である場合は特に。
>
> 確かに > 0 で判定されているサンプルもあるのですけど、
> 「= 0」の反対を「> 0」とすることに私は違和感を覚えるため、
> 整数比較を採用する場合は「(X And Mask) > 0」と書くのではなく、
> 代わりに「(X And Mask) <> 0」と書くようにしています。

確かに>0は符号付の事を考えると汎用性に欠けていたかもしれません。
「(X And Mask) = Mask」、「(X And Mask) <> 0」の条件で書いた方が確実ですね。
前者はMaskのすべてのビットを含む場合、後者はどれか1ビットでも含めばいい場合ですね。


>
> これが .NET 4 なら、「HasFlag メソッドを使う」という案もありますが、
> あれは引数が汎用の Enum 型なので、あまり好きでは無かったり。
引用返信 編集キー/
■63516 / inTopicNo.16)  Re[7]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ 魔界の仮面弁士 (46回)-(2012/09/03(Mon) 23:57:24)
No63514 (shu さん) に返信
> CBoolはBoolean型への変換を行う関数であって
> =0ならFalse
> <>0ならTrue
> にするというのが目的の関数ではないはず。

う〜ん。だとすると、何を Boolean 型に変換する事を目的としているのでしょう。
文字列からの変換専用でしょうか?


以下、Visual Basic 言語仕様 (Ver.11)より引用:

8.2 ブール値変換
》Boolean は数値型ではありませんが、列挙型の場合と同じように、
》数値型との間で縮小変換を行うことができます。
》リテラル True は、Byte の場合はリテラル 255、UShort の場合は 65535、(中略)
》リテラル False は、リテラル 0 に変換されます。
》数値のゼロは、リテラル False に変換されます。
》その他のすべての数値は、リテラル True に変換されます。
》Boolean から String への縮小変換では、(以下略)



> 実質的には変更されることはないのでしょうけど。

VB2 の頃は、True/False は存在したものの、CBool も Boolean 型も存在しなかったんですよね。
当時は True は -1 で、False は 0 を表す特別なキーワードでした。

それはさておき、VB 以外にも多くの言語系が、全ビットoff を FALSE としているようですね。
というよりも、他の定義を見たことが無いような…(あるのかな)。

一方、TRUE の内部表現は言語ごとに異なっていますね。1 だったり -1 だったり。

少なくとも、「FALSE ではない」「NOT FALSE は TRUE である」までは
どの言語系でも確定しているものと思いますが、その反対となる
NOT TRUE は、FALSE とは限らない処理系もありますね。


> 確かに>0は符号付の事を考えると汎用性に欠けていたかもしれません。
まぁ、MSDN Library のチュートリアルでも、「> 0」を使うように
表記されている例もあるので、それ自体は珍しい表現ではないのですけれどね。
引用返信 編集キー/
■63517 / inTopicNo.17)  Re[4]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ 魔界の仮面弁士 (47回)-(2012/09/04(Tue) 03:30:11)
No63505 (やんまー さん) に返信
> 単にe.DrawFocusRectangle()を呼び出していなかったからのようでした。
> 選択時に濃い紺色に反転するようになりました。

DrawFocusRectangle は、選択されている項目を色の背景を描画するものではなく、
フォーカス枠を描画するものかと。


>>ちなみに、e.DrawBackground() を呼び出すと、項目が選択されているかどうかに
>>あわせて、標準の背景色が描画されるようになっています。標準外の色で
>>描画したい場合には、前景色/背景色も自前で指定しましょう。
> すいません・・・
> この部分がわかりませんでした。
> この選択時の濃い紺色の色も変えられるということでしょうか・・?

そもそも、選択色が「濃い紺色」とは限らないですけれどね。
コントロールパネルから画面設定を変更することで、
ユーザーが別の色を選択色にするかも知れませんし。


標準以外の色にしたいなら、背景を e.DrawBackground() で描画する代わりに
 Using b As New SolidBrush(背景色)
  e.Graphics.FillRectangle(b, e.Bounds)
 End Using
などのように、任意色のブラシで塗ってやれば良いかと。

この時に、もしも 標準の前景色/背景色を調べたいなら、
 SystemColors.Highlight / SystemColors.HighlightText
 SystemColors.Window    / SystemColors.WindowText
などが使えます。


あるいは下記の「ListBoxのオーナードロー」などのように、
標準の色に拘らず、任意の色を使うこともできますね。
http://smdn.jp/programming/tips/ownerdraw/

引用返信 編集キー/
■63518 / inTopicNo.18)  Re[8]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ shu (59回)-(2012/09/04(Tue) 08:14:09)
No63516 (魔界の仮面弁士 さん) に返信
> ■No63514 (shu さん) に返信
>>CBoolはBoolean型への変換を行う関数であって
>>=0ならFalse
>><>0ならTrue
>>にするというのが目的の関数ではないはず。
> 
> う〜ん。だとすると、何を Boolean 型に変換する事を目的としているのでしょう。
> 文字列からの変換専用でしょうか?

内部表現の0とFalseの対応付けを意識した上で0がFalseであり0以外のある数をTrueであるという
仕様でInteger型の値を扱っているなら良いと思うのですが今回のようなフラグを表現している
場合はBooleanとみなすのは分かりにくいと思います。
フラグ以外でもIndexを0から9までループして0のときだけ処理を変えたいというときに

For Index = 0 To 9
    If CBool(Index) = False Then
        'Indexが0のときの処理
    Else
        'Indexが0以外のときの処理
    End If
Next 

と書くと分かりにくいと思うのですがどうでしょう?違うことのように感じるかもしれませんが
私の言いたいことはこういうことです。

引用返信 編集キー/
■63519 / inTopicNo.19)  Re[9]: Brushesのカラーコードを変数に出来ませんか?
□投稿者/ 魔界の仮面弁士 (48回)-(2012/09/04(Tue) 11:13:00)
No63518 (shu さん) に返信
> 違うことのように感じるかもしれませんが
> 私の言いたいことはこういうことです。

言いたいことは分かります。

一方で、自分の認識だと、ビットフラグは On/Off を表すために使われるので、
マスク結果を Boolean として扱うこともあるだろう、程度の認識です。

もちろん、Bitwise 演算結果を整数データとして扱った上で、それを
0 より大きいか、0 以外の値か、として比較する考え方も分かります。

# 数が多ければ BitArray や BitVector32 なども使えますが、
# 今回のケースでは冗長ですね。


現在の私は、<> 0 (あるいは、None 相当の列挙値との比較)を多用しますが、
だからといって、CBool 表現、>0 での比較、HasFlag 利用のいずれも、
他者のコードに修正を求めるほどの表現であるとまでは感じていません。


> 場合はBooleanとみなすのは分かりにくいと思います。
shu さんがそう思っている、という点は分かるのですが、どういう時に
CBool を使うものと考えておられるかが読み取れませんでした。なので、

>> CBoolはBoolean型への変換を行う関数であって
> 何を Boolean 型に変換する事を目的としているのでしょう。

この質問に対する答えもお聞きしたいです。


現時点で改めて私の疑問点を言えば、どちらかといえば CBool の意義についてなので。

> CBoolで変換するときに互換性のために0をFalseに変換し
> それ以外をTrueに変換はしていますが
> Integer And Integer の値はIntegerであってBooleanではないので
> このような意味が分かりにくい変換をすべきではないと思います。

「互換性のために」という文からは、以前は使われていたけれども
現在は推奨されない変換処理であるという意図を感じるのですが、だとすると
どういう時に CBool は使われるべきでしょうか。(あるいは、CBool 自体を
将来的には廃止するべきだ、という思いがあるのでしょうか)

# 元質問からズレてきているので、スレッドを分けた方が良いのかも。
引用返信 編集キー/
■63540 / inTopicNo.20)  Re[5]: Brushesのカラーコードを変数に出来ませんか?
 
□投稿者/ やんまー (10回)-(2012/09/05(Wed) 01:53:15)
魔界の仮面弁士 さん


ありがとうございます。

背景色、試してみます!




> ■No63505 (やんまー さん) に返信
>>単にe.DrawFocusRectangle()を呼び出していなかったからのようでした。
>>選択時に濃い紺色に反転するようになりました。
>
> DrawFocusRectangle は、選択されている項目を色の背景を描画するものではなく、
> フォーカス枠を描画するものかと。
>
>
> >>ちなみに、e.DrawBackground() を呼び出すと、項目が選択されているかどうかに
> >>あわせて、標準の背景色が描画されるようになっています。標準外の色で
> >>描画したい場合には、前景色/背景色も自前で指定しましょう。
>>すいません・・・
>>この部分がわかりませんでした。
>>この選択時の濃い紺色の色も変えられるということでしょうか・・?
>
> そもそも、選択色が「濃い紺色」とは限らないですけれどね。
> コントロールパネルから画面設定を変更することで、
> ユーザーが別の色を選択色にするかも知れませんし。
>
>
> 標準以外の色にしたいなら、背景を e.DrawBackground() で描画する代わりに
>  Using b As New SolidBrush(背景色)
>   e.Graphics.FillRectangle(b, e.Bounds)
>  End Using
> などのように、任意色のブラシで塗ってやれば良いかと。
>
> この時に、もしも 標準の前景色/背景色を調べたいなら、
>  SystemColors.Highlight / SystemColors.HighlightText
>  SystemColors.Window / SystemColors.WindowText
> などが使えます。
>
>
> あるいは下記の「ListBoxのオーナードロー」などのように、
> 標準の色に拘らず、任意の色を使うこともできますね。
> http://smdn.jp/programming/tips/ownerdraw/
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -