2006年06月29日

Windows.FormsのDataGridの列ヘッダ(ClumnHeader)の高さ

Windows.FormsのDataGridは列ヘッダの高さが変更できません。
列ヘッダに2行表示しようとしても、2行目が見切れてしまってだめです。

ここらへんに書いてありました。マイクロソフトの人が「ダメっ」って言っているらしいのでダメでしょう。

ただ、HeaderFontで、フォントサイズを大きくしても列ヘッダの枠の高さだけ変更になって、フォントサイズが変わらなかったので、列ヘッダのテキスト中に改行を入れたら2行表示できちゃいました。

なんででしょう??

だいぶはしょっちゃいますが
DataGrid.HeaderFont = new Font("", 18);

DataGridTableStyle ts = new DataGridTableStyle();
ts.HeaderFont = new Font("", 9);
なんてDataGridとTableStyleでフォントサイズを変えるとうまくいくみたいです。



ColumnHeaderHeight.PNG
posted by ほえ at 16:46| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年05月12日

DataGridでクリックされたセルの値の件

まず、どこがクリックされたかはDataGridのMouseDownイベントで
DataGrid.HitTestInfo hitTestInfo = dataGridSample.HitTest(e.X, e.Y);
でHitTestInfoを得ます。プロパティでRow、Columnが得られるので、
dataGridSample[hitTestInfo.Row, hitTestInfo.Column]
で得られます。
これだけだと、カラムヘッダをクリックしたときにhitTestInfo.Row = -1になってエラーになります。なので、
if(hitTestInfo.Row >= 0){}
とかしましょう。

これ、つい
((DataTable)dataGridSample.DataSource).Rows[hitTestInfo.Row][hitTestInfo.Column]
とかやってしまいそうなので。
これだと、カラムヘッダをクリックしてソートした時にクリック位置の値と一致しなくなります。
DataGridで表示している行と列は、DataTableの行と列とは別なのです。


これ、「あれ?一致しないって」今までに何回か間違えましたね。
posted by ほえ at 10:28| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年05月02日

フォームクローズ時に、「破棄されたオブジェクトにアクセスできません」と出ちゃった件

フォームにDataGridを配置して、フォームのKeyPrevieをtrueにします。フォームのKeyDownに
private void frmMain_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
 if(e.KeyCode == Keys.Escape)
 {
  this.Close();
 }
}
とすると、SetDataBindingメソッドでDataSourceが設定されている時、フォームでキーを押すと
「DataGridという名前の、破棄されたオブジェクトにアクセスできません」
とエラーになってしまいます。
DataGridでエラーになっているので、this.Close()する前に、
SetDataBinding(null, "")
なんてやるとエラーが出なくなりました。
これでいいのだろうか?

正しい解決方法は
KeyDownではなく、KeyUpでthis.Close()するべき
という事でした。
private void frmMain_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
 if(e.KeyCode == Keys.Escape)
 {
  this.Close();
 }
}


もし、画面にキャンセルボタンがあるのならば、フォームのCancelButtonプロパティにキャンセルボタンを割り当てると簡単です。Escが押されるとキャンセルボタンをクリックした事になります。
posted by ほえ at 12:10| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年04月29日

Excelのファイルを読込む件

ADO.NETで、接続文字列を
ODBCの場合
Driver={Microsoft Excel Driver (*.xls)};DBQ=C:\book1.xls
なんてします。
OLEDBの場合
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\dev\c#\ReadFromExcelFile\book1.xls;Extended Properties=Excel 8.0;
なんてします。
SQLは
SELECT * FROM [SHEET1$]
なんてシート名に$をつけます。
シートの先頭行がフィールド名になります。






名前年齢性別
ビル50
スティーブ51
リチャード53
リーナス34

だと、名前、年齢、性別がフィールド名になります。
接続文字列に
HDR=NO
を含めると先頭行もデータ行として扱われます。

string constr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\dev\c#\ReadFromExcelFile\book1.xls;Extended Properties=Excel 8.0";
OleDbConnection myConnection = new OleDbConnection(constr);
myConnection.Open();
string cmdSQL = " SELECT * FROM [SHEET1$] ";
OleDbCommand cmd = new OleDbCommand(cmdSQL, myConnection);
OleDbDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
MessageBox.Show(dr[0].ToString() + "でもいいですが、" + dr["名前"].ToString() + dr["年齢"].ToString() + dr["性別"].ToString());
}
myConnection.Close();

こんな感じ?
posted by ほえ at 14:03| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年04月13日

正規表現 PerlやRubyの場合

@ITの記事にある例なのですが、
(\d+)(\.(\d+)){3}
とすると、PerlやRubyだとグループの繰り返しの部分が、最後にマッチした文字列しかわからないようです。
192.168.0.1だと、192と1だけしか得られないと。
posted by ほえ at 18:01| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

正規表現 改行の件

正規表現で改行がわからなくなってしまいました。
Windowsなので、改行はCR+LFですね。
キャリッジリターン+ラインフィード。
\r\n。
文字コード13+文字コード10。
0x0D+0x0A。
0u000D+0u000D。
改行+復帰。

(ピリオド)は、「\n を除く任意の文字と一致します」とあったので、「ああ、改行以外にマッチするんだ」と思ってしまって、「\r\n以外にマッチする」と間違えていました。で、通常は.(ピリオド)は\rにもマッチするのですね。

Singlelineオプションを使って(?s).とすると、\rにも\nにもマッチします。
Multilneオプションを使って(?m).ではもちろん\rにのみマッチします。
両方指定して(?ms).では\r\nにマッチします。
^.または(?m)^.は、\rにマッチします。
.$は\rにマッチします。
ただ、(?ms).$は様子が違いました。
\r\nだけの文字列に(?ms).$だと、\rにも\nにもマッチするんですね。
ほほー。何故でしょう?
\nにだけマッチするのかと思いました。
さらに\r\n\r\nに(?ms).$だと、\r、\r、\nとマッチしました。1行目の\nはどうしてしまったんでしょう?
posted by ほえ at 12:57| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年04月09日

正規表現

よくわからない記号について調べてみました。

? 0回または1回以上の一致
*? 最短一致の*
+? 最短一致の+
?? 最短一致の? = できれば0回、できなければ1回の繰り返し
{n,m} n回以上m回以下の一致ですが、{n, m}のようにスペースを空けてはいけません。

\b \wと\Wの境界にマッチするよう指定します。単語境界でマッチする、つまり、英数字以外の文字で区切られた単語の、先頭か末尾の文字(の端っこ)でマッチするという事です。幅が0な訳です。

(?: ) キャプチャしません。キャプチャの必要ない部分を\1とか\2に入れないので、効率がいいです。

(?= ) 先読み表明(アサーション)。キャプチャはしません。\bの様に幅が0としてテストします。
例) abcdefghicdefgi中のghiが後に来るdefにマッチする。
def(?=ghi)
これは
(?=defghi)def
とも書けます。

(?<=) 戻り読み表明。
例) abcdefghicdefgi中のabcが前に来るdefにマッチする。
(?<=abc)def
※perlと違って、戻り読み表明中に可変長の正規表現を使えるようです。

(?(expression)yes|no) if-elseのように使います。expressionに一致したらyesの正規表現、しなければnoの正規表現がマッチします。noは省略可能。

(?(name)yes|no) 上記と同じ。ただnameが後方参照の番号または名前に指定できます。
例) a(?(b)b..|a..)は、aaaaabcacaではaaaaとabcaがマッチします。
aaaa aの次がbではないので、a..がマッチ
abca aの次がbなので、b..がマッチ

(?> ) バックトラッキングを行いません。
例)aaaに対して
a*a はマッチします。*で一度全部取り込みますが、最後にaがあるので、バックトラッキングを行って、グループに分けたとしたら(aa)(a)でマッチします。
(?>a*)a はマッチしません。*で全部取り込んでしまって、バックトラッキングしないのでマッチできないわけです。


perlですが、perlretut - Perl regular expressions tutorialがわかりやすかったです。
日本語版 perlretut - Perl の正規表現のチュートリアル。ありがたいです。
posted by ほえ at 17:00| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年04月05日

正規表現 前方参照

意味がわからなかったので、英語の方を見てみました。
たとえば、(?<1>a)(?<1>\1b)* とキャプチャ パターン (a)(ab)(abb) を使用すると、aababb が見つかります。
For example, (?<1>a)(?<1>\1b)* matches aababb, with the capturing pattern (a)(ab)(abb).
で、withが「と」になってたからわからなくなってしまったのでした。
たとえば、キャプチャ パターン(a)(ab)(abb)となる、(?<1>a)(?<1>\1b)*はaababbとマッチします。
という事でしょうか。日本語は難しいですね。
ただ、その後の
量指定子によるループが行われても、グループ定義はクリアされません。
は英語の方を読んでも、さっぱりです。

前方参照はbackreferenceでした。バックトラッキングはbacktrackingでした。
posted by ほえ at 15:37| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年04月03日

正規表現のグループとキャプチャ

@ITの記事から
123.45.678.9から、数字を拾いたい時
(\d+)(\.(\d+))+
の場合、
Match[0]=123.45.678.9
Group[0]=123.45.678.9
 Capture[0]=123.45.678.9
Group[1]=123
 Capture[0]=123
Group[2]=.9
 Capture[0]=.45
 Capture[1]=.678
 Capture[2]=.9
Group[3]=9
 Capture[0]=45
 Capture[1]=678
 Capture[2]=9
となります。つまり、使うのはMatchとCaptureだと。

数字だけでいいのでGroup[2]がいらないです。
(\d+)(?:\.(\d+))+
とすれば、
Match[0]=123.45.678.9
Group[0]=123.45.678.9
 Capture[0]=123.45.678.9
Group[1]=123
 Capture[0]=123
Group[2]=9
 Capture[0]=45
 Capture[1]=678
 Capture[2]=9
となって、スッキリです。
posted by ほえ at 20:28| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年03月29日

正規表現のオプションの指定方法

大文字と小文字を区別しない(IgnoreCase)とかオプションを指定するときに
Regex r = new Regex(@"abcdefg", IgnoreCase|RegexOptions.Multiline);
とかしますが、
Regex r = new Regex(@"(?im)abcdefg");
とも書けます。
この(?im)は(?-im)と書けばオプション指定がOFFになります。
また、パターンの途中に書いて、途中からON、OFFしたりできます。
Regex r = new Regex(@"ABC(?im)defg");

また、グループに対して指定することもできます。
Regex r = new Regex(@"(?im:abcdefg)");


MSDNの「正規表現のオプション」に記載されていました。
posted by ほえ at 00:16| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

2006年03月15日

インターフェースから実装する関数を隠す件

いまさらながら、IListインターフェースを実装するArrayクラスで、Addメソッドが無いんですが...と思って、調べてみました。

IListインターフェースのpublicメソッドにはAddや、Insert、Remove、RemoveAtなど、なんと言うか、いかにもリストらしいメソッドが定義されていますが、Arrayクラスにはありません。どこに行ってしまったんでしょうか?インターフェースのメンバは、暗黙のうちにpublicに指定されるので、そのメンバを実装してもpublicになります。アクセス修飾子は指定できないわけです。
他にどうすれば隠せるのだ?と思ったところ、AddをIList.Addとして、明示的に実装すると、直接外部からは見えなくなるのでした。
ヘルプにも「明示的なインターフェイスの実装」としてメンバの一覧の一番下に記載されていました。
public int IList.Add(object obj){〜}
例えば
Array [] a = new int[3];

a.Add(4) -> Addメソッドがないからコンパイルできません。
((IList)a).Add(4) -> コンパイルできるけど、実行時エラー。Arrayクラスで必ず NotSupportedExceptionをスローするように実装されているから。
ということです。
posted by ほえ at 15:31| Comment(0) | TrackBack(0) | C# | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。