Adsense_top

ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2014年8月14日木曜日

C# 動的に配置したコントロールの削除

動的にコントロールの追加と削除を繰り返していたら、例外が発生したので調べてみました。

同じ事をしないようにメモっておきます。

まず表示された例外は以下の様なものでした。
------------
型 'System.ComponentModel.Win32Exception' のハンドルされていない例外が System.Windows.Forms.dll で発生しました

追加情報:ウィンドウのハンドルを作成中にエラーが発生しました。
------------

削除は以下のように書いていました。

panel1.Controls.Clear();

この適当な書き方が悪かったようで、正しくコントロールによって使用されているリソースを開放する必要がありました。

正しくは以下のように書くべきでした。

for(int i = panel1.Controls.Count - 1; 0 <= i; i--) {
    panel1.Controls[i].Dispose();
}

※コレクションの後ろ側から開放している点が重要

結構な回数繰り返さないと発生しないので、例外も発生せず問題化していないプログラムも多いかも・・


2009年4月17日金曜日

C# DataGridViewの列ヘッダを縦書きにする

シャープ・メビウスのモニター募集に応募してみたら、アンケートにブログに関することがあり、前に立ち上げたまま何も書かずにいたココを思い出したので、これをきっかけ書きけ始めようと思います。
いきなりネタがないので、メモ代りにプログラミングのコードを書いておくことにします。

C#でWindows Form上のDataGridViewの列ヘッダを縦書きにするコードです。
ColumHeaderDefaultCellStyleのGdiVerticalFontをtrueにしても縦書きにならないようなので...

dataGridView1をFormに配置し列を1列追加しした状態です。
dataGridView1のColumnHeaderHeightModeをAutoSize以外にして、ColumnHeaderHeightを縦書き文字が納まるだけ高さを設定しておきます。
dataGridView1のCellPaintingイベントに以下のように書きます。

private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
DataGridView dv = (DataGridView)sender;
// 列ヘッダ
if (e.RowIndex < 0)
{
// 縦書き対象列か確認(1列目)
if (e.ColumnIndex == 0)
{
// 列ヘッダの背景と境界線を描画
e.Paint(e.ClipBounds,
DataGridViewPaintParts.Background
| DataGridViewPaintParts.Border);
StringFormat sf = new StringFormat();
//縦書きにする
sf.FormatFlags = StringFormatFlags.DirectionVertical
| StringFormatFlags.NoWrap;
//上詰め
sf.Alignment = StringAlignment.Near;
// 左右中央
sf.LineAlignment = StringAlignment.Center;
Rectangle rect = e.CellBounds;
// 境界線に文字が掛からないように、描画範囲を少し縮める。
rect.Inflate(-2, -2);
//縦書き文字の描画
string text = dv.Columns[e.ColumnIndex].HeaderText;
Font font = dv.ColumnHeadersDefaultCellStyle.Font;
Brush foreBrush = new SolidBrush(
dv.ColumnHeadersDefaultCellStyle.ForeColor);
e.Graphics.DrawString(text, font, foreBrush, rect, sf);
e.Handled = true;
}
}
}

こんな感じになります。



先に、ColumnHeaderHeightを縦書き文字が納まるだけ高さを設定しておくようにと書きましたが、実行時にヘッダ文字列を登録する場合は登録直後に、あらかじめ高さがわからない時はFormのLoadイベントに、以下のようにして高さを調整するコード書いておくとOKです。
Graphics graphics = dataGridView1.CreateGraphics();
Font font = dataGridView1.ColumnHeadersDefaultCellStyle.Font;
StringFormat sf = new StringFormat();
sf.FormatFlags = StringFormatFlags.DirectionVertical;
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
string s = dataGridView1.Columns["tateColumn"].HeaderText;
SizeF stringSize = graphics.MeasureString(s, font, 1000, sf);
if (dataGridView1.ColumnHeadersHeight < (int)stringSize.Height)
{
dataGridView1.ColumnHeadersHeight = (int)stringSize.Height + 5;
}


dataGridView1のColumnHeaderHeightModeをAutoSize以外にするのを忘れないにように。