質問者
DataGridView で DateTimePicker を表示できたりできなかったり

全般的な情報交換
-
下記情報を参考に DataGridView 上に DateTimePicker を表示させようとして
います。- 方法 : Windows フォーム DataGridView Cells でコントロールをホストする
http://msdn2.microsoft.com/ja-jp/library/7tas5c80(VS.80).aspx現状、DataGridView のセル上に DateTimePicker を表示できたりできなかった
りしています。何が原因かお分かりになる方、教えていただけませんか。以下
に、手順と動画を示します。まず、上記参考ページのコードを使って CalendarColumn というクラスを用意
し、ファイル CalendarColumn.cs としてソリューションに追加しておきます。A. 表示できたやり方
----
(1) DataGridView コントロールを Form 上に配置
(2) DataGridView にコラムを1つ追加
(3) そのコラムを CalendarColumn に結びつけるこれで実行すると、セルに今日の日付が入り、それをクリックすると
DateTimePicker が表示され、日付を選択できます。B. 表示できなかったやり方
----
(1) 下記構造のテーブルを用意 (primary key: id)id int not null
name varchar(50) not null
registered datetime not null(2) このテーブルのデータセットを Form にドラッグ&ドロップして DataGridView を作成
(3) registered フィールドに CalendarColumn を割り当てるこれで実行すると、registered セルには今日の日付は入っているのですが、ク
リックすると日付が消えて例外が発生します。メッセージの内容とデバッガからの情報を見ると、registered セルが空欄であ
るのがよくない感じがしています。A. では CalendarColumn を割り当てたセル
の日付は消えませんでしたが、B. の CalendarColumn を割り当てたセルの日付
はクリックした瞬間に消えています。
最初の日付の状態から、クリック後の状態に日付情報をコピーしなければなら
ないのでしょうが、その間でコピーが正しく行われておらず、日付が空白になっ
ているのかな?と思っていますが、もしそうなら、どうやったたら解決するの
かが分かりません。データセットとくっ付いている DataGridView がクリックされた瞬間にセルを
操作しているようにも見えています。本当はどうか分かりません。例外が発生する時の様子を動画にしていますので、下記 URL でご確認ください。
URL http://custar.s151.xrea.com/videos/calendarcolumn/calendarcolumn.html
環境
(C# 2008 Express Edition 英語版) + (SQL Server 2005 Express Edition 日本語版)C# 2008 英語版を使ったのは、C# 2005 日本語版でも同じ現象となったので、
2008 では改善されたかな、と期待して使ってみたまでです。
すべての返信
-
データベース (DataSet) 内に記録されている DateTime がセル上に表示されて
いれば、クリック時に DateTimePicker が正常表示されます。問題なのは、未設定のセルをクリックした時に、デフォルトで表示されている
DateTime.Now の値 (日時) が何かしらによって消されてしまうことです。消されているというよりは、空白のセルになった時に、元々表示されている日
時を空白セルにコピーできていない、というべきかも知れません。選択されている時に日時が表示されていれば、おそらく正常に
DateTimePicker が表示されると思います。
で、「元々表示されている日時を空白セルにコピー」という作業をどう記述す
ればよいのか全く分かりません。どなたかお分かりになりませんか?.net framework のソースがあれば探り当てられるかもしれないのですけど。
CalendarColumn.cs の一部を以下のようにすれば、例外は発せられません。
ちなみに CalendarColumn.cs は下記サンプルを用いています。URL http://msdn2.microsoft.com/ja-jp/library/7tas5c80(VS.80).aspx
コード ブロックpublic override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
CalendarEditingControl ctl = DataGridView.EditingControl as CalendarEditingControl;if (this.Value.ToString() != "") <----- この if() を追加
{
ctl.Value = (DateTime)this.Value;
}
}未設定セルをクリックした時には上記メソッドの引数 initialFormattedValue
が空白になっているのです。これが "2007/12/11 00:00:00" のような
DateTime 形式なのが正常です。空白の this.Value を DateTime にキャストしようとしているので、例外が出
ていると思います。空白にしてしまったのはどいつだ!?
-
-
- 空白の DataGridViewImageCell に何も表示させたくない - MSDN フォーラム
上記で得たことをヒントに CalendarColumn/Cell を見直してみました。
案の定、表示直後の CalendarCell および新規行の CalendarCell で日付が表
示されるようになりました。間違ったことをしていたら、詳しい方、ご指摘ください。
# 長い回り道だったなぁ。
コード ブロックpublic class CalendarColumn : DataGridViewColumn
{
public CalendarColumn() : base(new CalendarCell())
{
this.DefaultCellStyle.NullValue = DateTime.Now.ToShortDateString();
}ついでに、上記追加で下記 this.Value の if 文は不要になりました。
コード ブロックpublic class CalendarCell : DataGridViewTextBoxCell
{
public override void InitializeEditingControl(
int rowIndex,
object initialFormattedValue,
DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
CalendarEditingControl
ctl = DataGridView.EditingControl as CalendarEditingControl;
//if (this.Value != null && this.Value != DBNull.Value)
//{
ctl.Value = (DateTime)this.Value;
//}
}