2017年03月 / 01月≪ 12345678910111213141516171819202122232425262728293031≫02月

インフォメーション

FC2ブログで画像等を一括アップロードするソフトを地味に配布してます。
FC2ブログ用ファイルアップロードの最新版はこちら
(ベクター)FC2ブログ用ファイルアップロード

--.--.-- (--)

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


 |  --:--  |  スポンサー広告  |  Top↑

2008.06.24 (Tue)

DataGridViewのコンボボックスを1クリックでドロップダウン表示させたい

DataGridViewのDataGridViewComboBoxColumnでコンボボックスを表示させられるけど、
このコンボボックスでフォーカスがないときにドロップダウンする際、
選択→ドロップダウン
とドロップダウンさせるのに2回クリックしなきゃいけない。
シングルクリックでドロップダウンさせたい場合は
DataGridViewのCellClickイベントに下記の様な感じの処理を追加すれば簡単に出来る。
※Column4がDataGridViewComboBoxColumn

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == Column4.Index)
{
// 編集モードにする
dataGridView1.BeginEdit(false);
// 編集モードにしたので現在の編集コントロールを取得
DataGridViewComboBoxEditingControl edt =
dataGridView1.EditingControl as DataGridViewComboBoxEditingControl;
// ドロップダウンさせる
edt.DroppedDown = true;
}
}


dataGridView1.BeginEdit(false);
で編集モードにさせることによって
dataGridView1.EditingControl
から簡単にEditingControlが取得できるよってこと。

コンボボックスのセルなら全部1クリックでドロップダウンさせたい!て場合は

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if(dataGridView1.Columns[e.ColumnIndex].GetType().Equals(typeof(DataGridViewComboBoxColumn)))
{
// 編集モードにする
dataGridView1.BeginEdit(true);
// 編集モードにしたので現在の編集コントロールを取得
DataGridViewComboBoxEditingControl edt = dataGridView1.EditingControl as DataGridViewComboBoxEditingControl;
// ドロップダウンさせる
edt.DroppedDown = true;
}
}

型で判定すれば楽だね。

ちなみに
dataGridView1.BeginEdit(false);
の引数は、セルの内容を全選択するか否かのフラグ。trueにしても変わりなかった。
スポンサーサイト


 |  19:02  |  C#.NET  |  トラックバック(0)  |  コメント(3)  |  Top↑

2008.03.13 (Thu)

DataGridComboBoxにEnabledプロパティが欲しい

DataGridViewで設定できるコンボボックスのセルには「Enabled」というプロパティがない。
普通のComboBoxみたいにEnabledプロパティと、それに伴い無効(グレーアウト)してる表示が欲しい!

検索してもなかなか見つからないので、いろいろ四苦八苦しました。

Windows フォーム DataGridView Cells でコントロールをホストするを参考にDataGridViewTextBoxCellから継承したクラスを作るか

難しい。常時コンボのドロップダウンボタンは表示したいし、DataGridViewComboBoxCellクラスがあるんだから何とかならないものか。

DataGridViewComboBoxEditingControlにはEnabledプロパティがあるのでどうにか取れないか

DataGridViewComboBoxEditingControlのEnabledを変えても編集モード中しか表示が変わらないので無駄だった。

DataGridViewComboBoxCellを継承してpaintをoverrideして塗るか

いけそうかも

ヘルプを見てたらWindows フォーム DataGridView コントロールのボタン列にあるボタンを無効にするを発見

これじゃん!!これをコンボにすればいいだけじゃん!!

てな感じで
Windows フォーム DataGridView コントロールのボタン列にあるボタンを無効にするからコードをパクって
DataGridViewComboBoxColumn
DataGridViewComboBoxCell
を継承した
MyComboColumn
MyComboCell
クラスを作成し、EnabledはReadOnlyプロパティを利用して設定。
Paintをoverrideして、[Enabled=false]のときはグレーアウトしたボタンを描画するようにしました。

新しく追加した「Enabled」プロパティをちゃんと「ReadOnly」プロパティと明確に切り分けて使いたい場合は
DataGridViewも継承してDataGridViewからその処理を追加しないといけないみたいですが、
なるべく今あるクラスを使いたいので[ReadOnly]を使用してしまいます。

ComboBoxRendererというコンボを描くクラスの存在をはじめて知りました。

出来上がりはこんな感じ
[XPスタイルの場合]
up000019.jpg

[そうでない場合]
up000018.jpg


namespace[MyComboElements]にしてあるので、usingすると列の選択に出てきます。
up000012.jpg


以下ソースコード。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace MyComboElements
{
///
/// MyComboCellを使うColumnクラス
///

public class MyComboColumn : DataGridViewComboBoxColumn
{
public MyComboColumn()
: base()
{
// セルはMyCombCellを使用
base.CellTemplate = new MyComboCell();
}

public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
MyComboCell temp = value as MyComboCell;
if (value != null && temp == null)
{
throw new InvalidCastException();
}
base.CellTemplate = value;
}
}
}

///
/// Enabledを持ったコンボセル
///

public class MyComboCell : DataGridViewComboBoxCell
{
private bool enabled;

///
/// コンストラクタ
///

public MyComboCell()
: base()
{
enabled = true;
}

///
/// EnabledはReadOnlyを利用
///

public bool Enabled
{
get { return this.enabled; }
set
{
ReadOnly = !value;
}
}
///
/// ReadOnlyをoverride
///

public override bool ReadOnly
{
get
{
return base.ReadOnly;
}
set
{
base.ReadOnly = value;
this.enabled = !base.ReadOnly;
// セルを再描画
if (this.DataGridView != null)
this.DataGridView.InvalidateCell(this);
}
}

///
/// プロパティを追加したらCloneをオーバーライドしないとだめ
///

///
public override object Clone()
{
MyComboCell dataGridViewCell = base.Clone() as MyComboCell;
if (dataGridViewCell != null)
{
dataGridViewCell.Enabled = this.Enabled;
}
return dataGridViewCell;
}

///
/// 描画処理
///

///
///
///
///
///
///
///
///
///
///
///
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
// DataGridViewがなければ抜ける
if (this.DataGridView == null) return;

// 通常なら
if (this.Enabled)
{
// 通常描画
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
else
{
// Enabled = falseなら

// 背景
if ((paintParts & DataGridViewPaintParts.Background) ==
DataGridViewPaintParts.Background)
{
SolidBrush cellBackground =
new SolidBrush(cellStyle.BackColor);
graphics.FillRectangle(cellBackground, cellBounds);
cellBackground.Dispose();
}

// 枠線
if ((paintParts & DataGridViewPaintParts.Border) ==
DataGridViewPaintParts.Border)
{
PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
advancedBorderStyle);
}

// 描画するセルのサイズを取得
Rectangle comboArea = cellBounds;
Rectangle comboAdjustment =
this.BorderWidths(advancedBorderStyle);
comboArea.X += comboAdjustment.X;
comboArea.Y += comboAdjustment.Y;
comboArea.Height -= comboAdjustment.Height;
comboArea.Width -= comboAdjustment.Width;

// コンボボックスのボタン部分の位置とサイズを設定
Rectangle comboButtonArea = new Rectangle(comboArea.X + comboArea.Width - 18,
comboArea.Y + 1, 17, 18);

// コンボボックスのボタン部分を描画
if (ComboBoxRenderer.IsSupported)
{
ComboBoxRenderer.DrawDropDownButton(graphics, comboButtonArea, System.Windows.Forms.VisualStyles.ComboBoxState.Disabled);
}
else
{
// Visualスタイルをサポートしてない場合、コンボボックスからボタンを描画

// 描画用のコンボボックス
ComboBox cb = new ComboBox();
cb.Enabled = false; // グレーアウトしたボタンを取得するためfalseにする
// 横サイズをセルにあわせる
cb.Width = cellBounds.Width;
// bmp生成
Bitmap bmp = new Bitmap(cb.Width, cb.Height);
// bmpにコンボボックスを描画
cb.DrawToBitmap(bmp, new Rectangle(new Point(0,0), cb.Size));

// bmpのボタン部分のみのRectangle
Rectangle bmpButtonArea = new Rectangle(bmp.Width - 18, 2, 16, bmp.Height - 4);
// 描画先の位置を微調整
comboButtonArea.Y += 1;
comboButtonArea.Width -= 1;
comboButtonArea.Height -= 2;

// ボタン部分を描画
graphics.DrawImage(bmp, comboButtonArea, bmpButtonArea, GraphicsUnit.Pixel);

bmp.Dispose();

}

// 中身にテキストがあれば
if (this.FormattedValue is String)
{
// テキストも描画
TextRenderer.DrawText(graphics,
(string)this.FormattedValue,
this.DataGridView.Font,
comboArea, SystemColors.GrayText, (TextFormatFlags.VerticalCenter | TextFormatFlags.Default));
}
}
}
}
}


「XPスタイル」が無効の場合、仕方ないのでコンボボックスからボタン部分だけを持ってきて
描画するようにしました。
コンボボタンの位置とサイズを取得するのにもうちょっと方法がありそうだけどわかりませんでした。

Enabledを追加するだけでこんなにコード書く羽目になるとは思わなかった・・・・
フォーカスの四角とか選択中の背景色は・・・必要になったら追加します。


 |  19:05  |  C#.NET  |  トラックバック(0)  |  コメント(2)  |  Top↑
 | BLOGTOP | 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。