- PR -

DataGridViewのNotifyCurrentCellDirty()と、RowHeaderに表示されるペンマーク(?)について

投稿者投稿内容
@TK
常連さん
会議室デビュー日: 2004/11/10
投稿数: 39
投稿日時: 2007-08-22 12:24
Ahf様

ご返答ありがとうございます。


> # 普段VB使いなので書き方が間違っていたらごめんなさい

いえ、とんでもありません。
Ahf様のコードを下記のようにして実行させていただきました。


if (e.ColumnIndex == column1.Index)
{
 if (e.RowIndex == dataGridView1.NewRowIndex)
 {
  DataTable dt = (DataTable)dataGridView1.DataSource;
  DataRow dr = dt.NewRow();
  dt.Rows.Add(dr);
 }
 dataGridView1.CurrentCell.Value = "hoge";
}


不思議でしかたないのですが、やはり、二行追加されてしまいます。
動きとしては下記になります。

DataGridViewに3行(新規行込)あるとします。
3行目(新規行)をダブルクリックします。
すると2行追加されて全部で5行(新規行込)になります。
"hoge"のCellは4行目になります。
3行目には空の行が挿入されています。

新規行でない行をダブルクリックした際には、当然ですが当該Cellが"hoge"になるだけです。

かと言ってDataRow追加の処理を外すと、新規行ダブルクリック時に行追加が行われなくなってしまいます。


なんとなくこの挙動を見ていて感じることは、「行追加」と言う処理をPG内で行うのではなく、「値をCommitした」と通知できれば自動で新規行が追加されるようなプロセスが用意されているのではないかと言うことです。

そこら辺をもう少し調べてみようと思います。

以上、またよろしくお願いします。
@TK
常連さん
会議室デビュー日: 2004/11/10
投稿数: 39
投稿日時: 2007-08-22 12:30
隣の古柴様

ご回答ありがとうございます。


> なんかよく分からないのですが。。。

説明不足で申し訳ありません。


> 入力させない、ということは変更できないのではないでしょうか?
> 変更できないということはコミット以前の問題???

column1.ReadOnly = true;

にしていると言うことです。
UIからは仰る通り変更不可になりますが、PG内からの変更は可能でございます。

適切な回答になってますでしょうか・・・?


以上、またよろしくお願いします。
隣の古柴
ベテラン
会議室デビュー日: 2004/06/04
投稿数: 94
投稿日時: 2007-08-22 13:13
>UIからは仰る通り変更不可になりますが、PG内からの変更は可能でございます。

それで

> dataGridView1.CurrentCell.Value = "hoge";
> dataGridView1.NotifyCurrentCellDirty(true);

ValueプロパティにセットしてNotifyCurrentCellDirtyメソッドを呼び出して
いると。。。納得です。

余計な手間をかけさせてしまいました(汗
@TK
常連さん
会議室デビュー日: 2004/11/10
投稿数: 39
投稿日時: 2007-08-22 13:46
隣の古柴様

たびたびご回答をありがとうございます。


> 余計な手間をかけさせてしまいました(汗

こちらこそ説明不足と駄文、失礼しました。
投稿は、「いかに要点を適切に伝えるか」を気にかけて書くようにしているつもりなのですが、なかなか難しいものですね。



・NotifyCurrentCellDirty()を使用する方法
依然調査中です。
引き続き情報提供いただけたら幸いです。


・DataSource(DataTable)へ行追加する方法
関係があるか分かりませんが、判明したことがありましたので追加記述させていただきます。

if (e.ColumnIndex == column1.Index)
{
 if (e.RowIndex == dataGridView1.NewRowIndex)
 {
  DataTable dt = (DataTable)dataGridView1.DataSource;
  DataRow dr = dt.NewRow();
  dt.Rows.Add(dr);  // A
 }
 dataGridView1.CurrentCell.Value = "hoge";
}

上記、Aの行が実行されるまでは

dataGridView1.Rows.Countは3
dt.Rows.Countは2

となっておりますが、Aの行が実行されると

dataGridView1.Rows.Countは5
dt.Rows.Countは3

になってしまいます。
・・・この結果はいかがなものでしょう。


以上、またよろしくお願いします。
隣の古柴
ベテラン
会議室デビュー日: 2004/06/04
投稿数: 94
投稿日時: 2007-08-22 15:49
完全に右から左に流すだけのレスに成り下がってますが(汗

http://msdn2.microsoft.com/ja-jp/library/system.data.datatable.rows(VS.80).aspx

を見ますと

####### 以下引用 #######

新しい DataRow を作成するには、NewRow メソッドを使用して、新しいオブジェクトを返す必要があります。このようなオブジェクトは、DataColumn オブジェクトのコレクションを通じて DataTable に対して定義されたスキーマに従って、自動的に設定されます。新しい行を作成し、行内の各列の値を設定した後、Add メソッドを使用してこの行を DataRowCollection に追加します。

####################

とあり、さらに、こんな一文があります。

####### 以下引用 #######

コレクション内の各 DataRow は、テーブル内のデータ行を表します。行内の列の値に対して行った変更をコミットするには、AcceptChanges メソッドを呼び出す必要があります。

####################

さっぱり何が何やらわかりません(汗

識者の方のレスを待つ次第です。
まるく
大ベテラン
会議室デビュー日: 2004/01/09
投稿数: 181
投稿日時: 2007-08-22 17:13
とりあえず
コード:
if (e.ColumnIndex == column1.Index) 
{ 
 if (e.RowIndex == dataGridView1.NewRowIndex) 
 { 
  DataTable dt = (DataTable)dataGridView1.DataSource; 
    dt.AcceptChanges();
 } 
 dataGridView1.CurrentCell.Value = "hoge"; 
}

@TK
常連さん
会議室デビュー日: 2004/11/10
投稿数: 39
投稿日時: 2007-08-22 19:26
隣の古柴様 まるく様

ご回答ありがとうございました。
おかげさまで問題が解決いたしました。

お二人にご教示いただいたAcceptChanges()を使うことで要件を満たせることを確認いたしました。

ソースはまるく様の投稿と同じですが、下記になります。


if (e.ColumnIndex == column1.Index)
{
 if (e.RowIndex == dataGridView1.NewRowIndex)
 {
  DataTable dt = (DataTable)dataGridView1.DataSource;
  dt.AcceptChanges();
 }
 dataGridView1.CurrentCell.Value = "hoge";
}


PGから、バインドされたDataGridViewの新規行を追加するためには

DataGridView.NotifyCurrentCellDirty()を使用する・・・NG
DataSource(DataTable)に直接行追加・・・NG
DataTable.AcceptChanges()を使用する・・・OK

と言うことでした。


ご協力いただき、ありがとうございました。
本スレッドがどなたかの手助けに役立てば幸いです。
隣の古柴
ベテラン
会議室デビュー日: 2004/06/04
投稿数: 94
投稿日時: 2007-08-23 09:57
便乗質問になってしまうのですが・・。
この問題をVBで再現させようと下記のコードをトレースすると「B」の
行で

'System.Windows.Forms.BindingSource'のオブジェクトを
型'System.Data.DataTable'にキャストできません。

というエラーが発生します。

コード:

If e.RowIndex = DataGridView1.NewRowIndex Then

Dim dt As DataTable
dt = DataGridView1.DataSource ' B
dt.AcceptChanges()


End If




単純にObject型からDataTable型にcastしてやればいいかと思いました
が、その方法が判りません。

どなたかご教示頂ければ幸いです。

[ メッセージ編集済み 編集者: 隣の古柴 編集日時 2007-08-23 09:59 ]

スキルアップ/キャリアアップ(JOB@IT)