┏第29号━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .NETプログラミング研究 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
──<メニュー>───────────────────────
■.NET質問箱
・DataGridの列ヘッダテキストの配置方法を変更する
■.NET Tips
・型のすべてのメンバを取得する
───────────────────────────────
───────────────────────────────
■.NET質問箱
───────────────────────────────
「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込
まれた.NETプログラミングに関する投稿をQ&A形式にまとめ、紹介
します。
[URL]どぼん!のプログラミング掲示板
http://dobon.net/vb/bbs.html
●DataGridの列ヘッダテキストの配置方法を変更する
【質問】
Windowsアプリケーションで、DataGridコントロールの列ヘッダのテキ
ストだけ中央に配置されるようにしたいのですが、どのようにすれば
よいのでしょうか?「DataGridの列のテキストの配置方法を変更する」
で紹介されているように、DataGridColumnStyleのAlignmentプロパテ
ィを変更する方法では、ヘッダとデータの両方のテキストの配置が変
更されてしまいます。
[URL].NET Tips - DataGridの列のテキストの配置方法を変更する
http://dobon.net/vb/dotnet/datagrid/columnalignment.html
【回答】
この問題で困っていらっしゃる方が多いようで(あるいは、簡単な解
決法があって当たり前のはずなのに、なかなか見つからないというこ
とかもしれませんが)、同様の質問を何度かいただいております。
結論から言いますと、.NET Frameworkにはこの問題を解決する方法が
用意されていません。ですので、普通の方法では、今のところ、どう
しようもありません。
何か方法がないものかと考えたところ、発想を逆転させ、ヘッダの配
置を変えるのではなく、逆にデータの配置を変えるという方法を思い
つきました。セルの表示方法は、DataGridColumnStyleのPaintメソッ
ドをオーバーライドすることにより変更することができますので、
Alignmentプロパティには列ヘッダの配置を指定し、Paintメソッドで
セル内の文字列をAlignmentプロパティとは別の配置方法で描画すると
いうことができます。
この考え方にしたがって、セル内の文字列の配置方法を変更できる
DataGridColumnStyleの派生クラスを作成すると、例えば次のようにな
ります。
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
namespace Dobon.Samples.Forms
{
///
/// セルのテキスト配置を列ヘッダと別に設定できる
/// DataGridTextBoxColumnクラス
///
public class DataGridCellAlignColumn : DataGridTextBoxColumn
{
//テキストをセルに描画する際のマージン
//これがないと、描画位置が上になりすぎる
Point _margin = new Point(0, 2);
HorizontalAlignment _cellAlign = HorizontalAlignment.Left;
///
/// セルのテキスト配置方法
///
public HorizontalAlignment CellAlign
{
get
{
return _cellAlign;
}
set
{
_cellAlign = value;
}
}
protected override void Edit(
CurrencyManager source,
int rowNum,
Rectangle bounds,
bool readOnly,
string instantText,
bool cellIsVisible)
{
base.Edit(source, rowNum, bounds, readOnly,
instantText, cellIsVisible);
//TextBoxのテキスト配置を変更する
this.TextBox.TextAlign = _cellAlign;
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
Brush backBrush,
Brush foreBrush,
bool alignToRight)
{
string text =
GetColumnValueAtRow(source, rowNum).ToString();
StringFormat sf = new StringFormat();
//配置方法により、描画方法を変更する
switch (_cellAlign)
{
case HorizontalAlignment.Left:
sf.Alignment = StringAlignment.Near;
break;
case HorizontalAlignment.Center:
sf.Alignment = StringAlignment.Center;
break;
case HorizontalAlignment.Right:
sf.Alignment = StringAlignment.Far;
break;
}
sf.FormatFlags = StringFormatFlags.NoWrap;
if (alignToRight)
sf.FormatFlags |=
StringFormatFlags.DirectionRightToLeft;
//背景を塗りつぶす
g.FillRectangle(backBrush, bounds);
RectangleF rectf = new RectangleF(
bounds.X, bounds.Y, bounds.Width, bounds.Height);
rectf.Inflate(-_margin.X, -_margin.Y);
//文字列を描画する
g.DrawString(text, this.DataGridTableStyle.DataGrid.Font,
foreBrush, rectf, sf);
sf.Dispose();
}
}
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Data
Namespace Dobon.Samples.Forms
'''
''' セルのテキスト配置を列ヘッダと別に設定できる
''' DataGridTextBoxColumnクラス
'''
Public Class DataGridCellAlignColumn
Inherits DataGridTextBoxColumn
'テキストをセルに描画する際のマージン
'これがないと、描画位置が上になりすぎる
Private _margin As New Point(0, 2)
Private _cellAlign As HorizontalAlignment = _
HorizontalAlignment.Left
'''
''' セルのテキスト配置方法
'''
Public Property CellAlign() As HorizontalAlignment
Get
Return _cellAlign
End Get
Set(ByVal Value As HorizontalAlignment)
_cellAlign = Value
End Set
End Property
Protected Overloads Overrides Sub Edit( _
ByVal [source] As CurrencyManager, _
ByVal rowNum As Integer, _
ByVal bounds As Rectangle, _
ByVal [readOnly] As Boolean, _
ByVal instantText As String, _
ByVal cellIsVisible As Boolean)
MyBase.Edit([source], rowNum, bounds, [readOnly], _
instantText, cellIsVisible)
'TextBoxのテキスト配置を変更する
Me.TextBox.TextAlign = _cellAlign
End Sub
Protected Overloads Overrides Sub Paint( _
ByVal g As Graphics, _
ByVal bounds As Rectangle, _
ByVal [source] As CurrencyManager, _
ByVal rowNum As Integer, _
ByVal backBrush As Brush, _
ByVal foreBrush As Brush, _
ByVal alignToRight As Boolean)
Dim [text] As String = _
GetColumnValueAtRow([source], rowNum).ToString()
Dim sf As New StringFormat
'配置方法により、描画方法を変更する
Select Case _cellAlign
Case HorizontalAlignment.Left
sf.Alignment = StringAlignment.Near
Case HorizontalAlignment.Center
sf.Alignment = StringAlignment.Center
Case HorizontalAlignment.Right
sf.Alignment = StringAlignment.Far
End Select
sf.FormatFlags = StringFormatFlags.NoWrap
If alignToRight Then
sf.FormatFlags = sf.FormatFlags Or _
StringFormatFlags.DirectionRightToLeft
End If
'背景を塗りつぶす
g.FillRectangle(backBrush, bounds)
Dim rectf As New RectangleF( _
bounds.X, bounds.Y, bounds.Width, bounds.Height)
rectf.Inflate(-_margin.X, -_margin.Y)
'文字列を描画する
g.DrawString([text], _
Me.DataGridTableStyle.DataGrid.Font, _
foreBrush, rectf, sf)
sf.Dispose()
End Sub
End Class
End Namespace
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
このDataGridCellAlignColumnクラスを使用するには、使用したい列の
列スタイルにDataGridCellAlignColumnオブジェクトを設定し、
DataGridCellAlignColumnのAlignmentプロパティに列ヘッダテキスト
の配置を指定し、CellAlignプロパティにセル内の文字列の配置を指定
します。
列スタイルを設定する詳しい方法は、次のページをご覧ください。
[URL]DataGridの列の幅を変更する
http://dobon.net/vb/dotnet/datagrid/columnwidth.html
○この記事の基になった掲示板のスレッド
[題名] DataGridのスタイルに関して
[投稿者(敬称略)] TY、FLOWER KING、管理人
[URL] http://dobon.net/vb/bbs/log3-1/208.html
───────────────────────────────
■.NET Tips
───────────────────────────────
●型のすべてのメンバを取得する
ここでは次のようなクラスが定義されているものとし、このクラスの
メンバを取得します。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
Namespace MyNamespace
Public Class [MyClass]
'列挙型
Public Enum PublicEnum
One
Two
End Enum
'フィールド
Private PrivateField As Integer
'プロパティ
Public ReadOnly Property PublicProperty() As Integer
Get
Return PrivateField
End Get
End Property
'コンストラクタ
Public Sub New(ByVal val As Integer)
PrivateField = val
End Sub
'メソッド
Public Overloads Function PublicMethod( _
ByVal str As String) As String
str = "PublicMethodが呼び出されました。" + str
Return str
End Function
Public Overloads Function PublicMethod() As String
Return PublicMethod("")
End Function
End Class
End Namespace
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
namespace MyNamespace
{
public class MyClass
{
//列挙型
public enum PublicEnum
{
One,
Two,
}
//フィールド
private int PrivateField;
//プロパティ
public int PublicProperty
{
get
{
return PrivateField;
}
}
//コンストラクタ
public MyClass(int val)
{
PrivateField = val;
}
//メソッド
public string PublicMethod(string str)
{
str = "PublicMethodが呼び出されました。" + str;
return str;
}
public string PublicMethod()
{
return PublicMethod("");
}
}
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
ある型(クラス、値型、配列、インターフェイス、ポインタ、列挙体)
のすべてのメンバ(プロパティ、メソッド、フィールド、イベントな
ど)を取得するには、TypeクラスのGetMembersメソッドを呼び出しま
す。
上記MyClassクラスのすべてのメンバ(継承されたメンバを除く)を列
挙するには、次のようにします。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'Imports System.Reflection
'が宣言されているものとする
'MyClassクラスのTypeオブジェクトを取得する
Dim t As Type = GetType(MyNamespace.MyClass)
'メンバを取得する
Dim members As MemberInfo() = t.GetMembers( _
BindingFlags.Public Or BindingFlags.NonPublic Or _
BindingFlags.Instance Or BindingFlags.Static Or _
BindingFlags.DeclaredOnly)
Dim m As MemberInfo
For Each m In members
'メンバの型と、名前を表示する
Console.WriteLine("{0} - {1}", m.MemberType, m.Name)
Next
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//using System.Reflection;
//が宣言されているものとする
//MyClassクラスのTypeオブジェクトを取得する
Type t = typeof(MyNamespace.MyClass);
//メンバを取得する
MemberInfo[] members = t.GetMembers(
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.DeclaredOnly);
foreach (MemberInfo m in members)
{
//メンバの型と、名前を表示する
Console.WriteLine("{0} - {1}", m.MemberType, m.Name);
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
この結果は、次のように表示されます。
Field - PrivateField
Method - get_PublicProperty
Method - PublicMethod
Method - PublicMethod
Constructor - .ctor
Property - PublicProperty
NestedType - PublicEnum
上記のように検索するメンバの種類を指定するために、BindingFlags
を指定してGetMembersメソッドを呼び出します。GetMembersメソッド
でよく使用されるBindingFlagsには次のようなものがあります。
メンバ名:Public
説明:パブリックメンバを検索の対象に加える。
値:16
メンバ名:NonPublic
説明:パブリックでないメンバを検索の対象に加える。
値:32
メンバ名:Instance
説明:非静的メンバ(インスタンスメンバ)を検索の対象に加える。
値:4
メンバ名:Static
説明:静的メンバを検索の対象に加える。
値:8
メンバ名:DeclaredOnly
説明:継承されたメンバを検索の対象にしない。
値:2
メンバ名:FlattenHierarchy
説明:階層構造の上位の静的メンバを検索の対象に加える。
値:64
GetMembersメソッドをパラメータなしで呼び出したときは、
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static
(つまり、28)を指定したのと同じになります。
先に示したコードで、パラメータを指定しないでGetMembersメソッド
を呼び出したとき、その結果は次のようになります。
Method - GetHashCode
Method - Equals
Method - ToString
Method - get_PublicProperty
Method - PublicMethod
Method - PublicMethod
Method - GetType
Constructor - .ctor
Property - PublicProperty
NestedType - PublicEnum
ある型のすべてのプロパティ、メソッド、フィールド、コンストラク
タ、インターフェイス、イベント、入れ子になっている型を取得する
には、それぞれ、GetProperties、GetMethods、GetFields、
GetInterfaces、GetEvents、GetNestedTypesメソッドを使用します。
使い方は、戻り値が違う以外は、GetMembersメソッドと同じです。
次にGetMethodsメソッドを使った例を示します。ここではMyClassクラ
スのすべてのメソッドを、そのアクセシビリティ、戻り値、パラメー
タ情報などとともに表示しています。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'Imports System.Reflection
'が宣言されているものとする
'MyClassクラスのTypeオブジェクトを取得する
Dim t As Type = GetType(MyNamespace.MyClass)
'メソッドの一覧を取得する
Dim methods As MethodInfo() = t.GetMethods( _
BindingFlags.Public Or BindingFlags.NonPublic Or _
BindingFlags.Instance Or BindingFlags.Static)
Dim m As MethodInfo
For Each m In methods
'特別な名前のメソッドは表示しない
If m.IsSpecialName Then
GoTo ContinueForEach1
End If
'アクセシビリティを表示
'ここではIs...プロパティを使っているが、
'Attributesプロパティを調べても同じ
If m.IsPublic Then
Console.Write("public ")
End If
If m.IsPrivate Then
Console.Write("private ")
End If
If m.IsAssembly Then
Console.Write("internal ")
End If
If m.IsFamily Then
Console.Write("protected ")
End If
If m.IsFamilyOrAssembly Then
Console.Write("internal protected ")
End If
'その他修飾子を表示
If m.IsStatic Then
Console.Write("static ")
End If
If m.IsAbstract Then
Console.Write("abstract ")
Else If m.IsVirtual Then
Console.Write("virtual ")
End If
'戻り値を表示
If m.ReturnType.Equals(Type.GetType("System.Void")) Then
Console.Write("void ")
Else
Console.Write((m.ReturnType.ToString() + " "))
End If
'メソッド名を表示
Console.Write(m.Name)
'パラメータを表示
Dim prms As ParameterInfo() = m.GetParameters()
Console.Write("(")
Dim i As Integer
For i = 0 To prms.Length - 1
Dim p As ParameterInfo = prms(i)
Console.Write((p.ParameterType.ToString() + " " + p.Name))
If prms.Length - 1 > i Then
Console.Write(", ")
End If
Next
Console.Write(")")
Console.WriteLine()
ContinueForEach1:
Next
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//using System.Reflection;
//が宣言されているものとする
//MyClassクラスのTypeオブジェクトを取得する
Type t = typeof(MyNamespace.MyClass);
//メソッドの一覧を取得する
MethodInfo[] methods = t.GetMethods(
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static);
foreach (MethodInfo m in methods)
{
//特別な名前のメソッドは表示しない
if (m.IsSpecialName)
continue;
//アクセシビリティを表示
//ここではIs...プロパティを使っているが、
//Attributesプロパティを調べても同じ
if (m.IsPublic)
Console.Write("public ");
if (m.IsPrivate)
Console.Write("private ");
if (m.IsAssembly)
Console.Write("internal ");
if (m.IsFamily)
Console.Write("protected ");
if (m.IsFamilyOrAssembly)
Console.Write("internal protected ");
//その他修飾子を表示
if (m.IsStatic)
Console.Write("static ");
if (m.IsAbstract)
Console.Write("abstract ");
else if (m.IsVirtual)
Console.Write("virtual ");
//戻り値を表示
if (m.ReturnType == typeof(void))
Console.Write("void ");
else
Console.Write(m.ReturnType.ToString() + " ");
//メソッド名を表示
Console.Write(m.Name);
//パラメータを表示
ParameterInfo[] prms = m.GetParameters();
Console.Write("(");
for (int i = 0; i < prms.Length; i++)
{
ParameterInfo p = prms[i];
Console.Write(p.ParameterType.ToString() + " " + p.Name);
if (prms.Length - 1 > i)
Console.Write(", ");
}
Console.Write(")");
Console.WriteLine();
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
結果は次のようになります。
protected virtual void Finalize()
public virtual System.Int32 GetHashCode()
public virtual System.Boolean Equals(System.Object obj)
public virtual System.String ToString()
public System.String PublicMethod(System.String str)
public System.String PublicMethod()
public System.Type GetType()
protected System.Object MemberwiseClone()
===============================
■このマガジンの購読、購読中止、バックナンバー、説明に関しては
次のページをご覧ください。
http://www.mag2.com/m/0000104516.htm
■発行人・編集人:どぼん!
(Microsoft MVP for Visual Basic, Oct 2003-Oct 2004)
http://dobon.net
dobon_info@yahoo.co.jp
■ご質問等はメールではなく、掲示板へお願いいたします。
http://dobon.net/vb/bbs.html
■上記メールアドレスへのメールは確実に読まれる保障はありません
(スパム、ウィルス対策です)。メールは下記URLのフォームメール
から送信してください。
http://dobon.net/mail.html
Copyright (c) 2003 - 2004 DOBON! All rights reserved.
===============================