C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: DataGridView内のボタンクリック時にその行を確定


(過去ログ 172 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■99235 / inTopicNo.1)  DataGridView内のボタンクリック時にその行を確定
  
□投稿者/ nyohhiroki (1回)-(2022/02/24(Thu) 02:16:18)

分類:[.NET 全般] 

DataGridViewにボタン列を作成し、そのボタンをクリックした際にその行の入力値に対して処理をしたいと考えています。
しかし、そのボタンを押した時の行の入力状況がコミットされていない為、その後の処理が上手くいきません。
CommitEdit()を使えば、強制的にコミット出来るかと考えたのですが、上手くいかず[IsCurrentRowDirty]がどうしてもTrueになってしまいます。
※後続の処理では、その行をImportRowしようとしているのですが、コミットされていないDataRowのRowStateはDetachedになってしまって、ImportRowが出来ない。

コード内で強制的にコミットさせて、そのDataGridviewの[IsCurrentRowDirty]をFalseにする方法を教えていただけませんでしょうか。




        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable DT1 = new DataTable("DT1");
            DT1.Columns.Add("Col1");
            DT1.Columns.Add("Col2");
            this.dataGridTest.DataSource = DT1;

            DataGridViewButtonColumn CopyBtnColumn = new DataGridViewButtonColumn();
            this.dataGridTest.Columns.Insert(0, CopyBtnColumn);
            CopyBtnColumn.UseColumnTextForButtonValue = true;
            CopyBtnColumn.Text = "TEST";
            CopyBtnColumn.Name = "TEST";
        }

        private void dataGridTest_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
        {
            if (this.dataGridTest.Columns[e.ColumnIndex].Name == "TEST")
            {
                this.dataGridTest.CommitEdit(DataGridViewDataErrorContexts.Commit);
                MessageBox.Show(this.dataGridTest.IsCurrentRowDirty.ToString());
            }
        }


引用返信 編集キー/
■99236 / inTopicNo.2)  Re[1]: DataGridView内のボタンクリック時にその行を確定
□投稿者/ Hongliang (1215回)-(2022/02/24(Thu) 09:12:25)
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.datagridview.commitedit
> 編集モードを終了せずに、現在のセルの変更をデータ キャッシュにコミットします。
CommitEditは現在のセルが対象です。
ボタン列のクリック時は現在のセルはボタン列に移っていますし、その際にその前のセルの編集は完了しコミットされているので、二重に無意味になります。

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.iscurrentrowdirty
(翻訳がだいぶ怪しいので英語版)
> To commit row changes programmatically, call the form's Validate method. If your data source is a BindingSource, you can also call BindingSource.EndEdit.
IsCurrentRowDirtyの注釈にこのようにあります。
つまりFormのValidateメソッドを呼べば、行の変更がコミットされます。

質問の本質的には、IsCurrentRowDirtyがtrueになるのが問題ではなく、現在の行のRowStateがDetachedであるのが問題であるようなので、対象行を指すDataRowViewのEndEditを呼び出す方法もあります。
引用返信 編集キー/
■99237 / inTopicNo.3)  Re[1]: DataGridView内のボタンクリック時にその行を確定
□投稿者/ WebSurfer (2453回)-(2022/02/24(Thu) 09:42:23)
No99235 (nyohhiroki さん) に返信

そもそも何がしたいのでしょう?

データソース(SQL Server, CSV, XML 等)の内容を DataSet/DataTable に取り込
んで、それを DataGridView に表示し、ユーザーがその表示を見て編集し、編集結
果を元のデータソースに書き戻すというような話ではなかろうかと想像してますが、
そうであるとすると XY 問題になっているような気がします。

想像がハズレでした多失礼しました。でも、当たりだったら以下のレスを読んでく
ださい。

DataSet / DataTable + DataGridView の典型的な使い方は上の想像に書いたよう
なことで、具体的にどういうことかは以下の記事の「非接続型のデータ更新」のセ
クションの図1と図2を見てください。文章は読まなくてもいいので図だけ見てく
ださい。

DB 設計者のための明解 ADO.NET 第 1 回
https://docs.microsoft.com/ja-jp/previous-versions/cc482903%28v=msdn.10%29

図2の DataSet 右側に BindingSource / BindingNavigator 経由で DataGridView
が接続されていると思ってください。

ユーザーが DataGridView を操作(行の削除・追加・訂正)した結果は図1にある
ように DataSet / DataTable に反映されます。ユーザーの編集操作が終わったら
Update メソッドで図1の編集結果が一度に DB に反映されます。そういうアプリ
が以下の記事のように Visual Studio のウィザードを使って簡単に作れるように
なっています。

新しいデータ ソースの追加
https://docs.microsoft.com/ja-jp/visualstudio/data-tools/add-new-data-sources?view=vs-2022

上の記事の図では TextBox に表示するようになっていますが、Data Sources
ウィンドウの Customer ドロップダウンの選択で DataGridView にもできます。

引用返信 編集キー/
■99238 / inTopicNo.4)  Re[1]: DataGridView内のボタンクリック時にその行を確定
□投稿者/ 魔界の仮面弁士 (3297回)-(2022/02/24(Thu) 10:44:08)
No99235 (nyohhiroki さん) に返信
> CommitEdit()を使えば、強制的にコミット出来るかと考えたのですが、
> 上手くいかず[IsCurrentRowDirty]がどうしてもTrueになってしまいます。

private DataGridViewButtonColumn CopyBtnColumn;
private DataTable DT1;
private void Form1_Load(object sender, EventArgs e)
{
  this.DT1 = new DataTable("DT1");
  this.DT1.Columns.Add("Col1");
  this.DT1.Columns.Add("Col2");
  this.dataGridTest.DataSource = this.DT1;
  this.dataGridTest.Columns.Insert(0, this.CopyBtnColumn = new DataGridViewButtonColumn());
  this.CopyBtnColumn.UseColumnTextForButtonValue = true;
  this.CopyBtnColumn.Text = "TEST";
  this.CopyBtnColumn.Name = "TEST";
}

private void dataGridTest_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
  if (e.ColumnIndex == this.CopyBtnColumn.Index)
  {
    var rowView = ((DataGridView)sender).Rows[e.RowIndex].DataBoundItem as DataRowView;
    if (rowView == null)
    {
      this.label1.Text = "";
    }
    else
    {
      rowView.EndEdit(); // ★

      string[] lines = {
        "Dirty:" + ((DataGridView)sender).IsCurrentRowDirty,
        "RowState:" + rowView.Row.RowState,
        "Col1:" + rowView["Col1"],
        "Col2:" + rowView["Col2"]
      };
      this.label1.Text = string.Join("\r\n", lines);
    }
  }
}
引用返信 編集キー/
■99239 / inTopicNo.5)  Re[1]: DataGridView内のボタンクリック時にその行を確定
□投稿者/ nyohhiroki (2回)-(2022/02/24(Thu) 17:31:44)
皆さま ありがとうございます。

元々やろうとしていたのは、ユーザーに編集させるDataGridViewに「その行をコピーする」というボタンを配置しようとしていました。
そのコピーの方法を下記のように[ImportRow]メソッドを使ってやろうとしていたのですが、同一行内での編集後→コピーボタン押下、をするとコピーしようとする行がコミット前の状態となってしまい、ユーザー操作の直感と合わないというのをどうすればいいか、と悩んでいました。

//DataGridViewのデータソースにImportRowをする
DataRowView DTRowView = this.DGView.Rows[RowNumber].DataBoundItem as DataRowView;
DataRow DTRow = DTRowView.Row;
DataTable DT = (DataTable)this.DGView.DataSource;
DT.ImportRow(DTRow);


最終的に頂いた方法では
ImportするDataRowを作るDataRowViewのEndEdit()にて実現することが出来ました。
※Importしようとする部分で下記の1行を追加

DTRowView.EndEdit();


ありがとうございました。


解決済み
引用返信 編集キー/
■99240 / inTopicNo.6)  Re[2]: DataGridView内のボタンクリック時にその行を確定
□投稿者/ 魔界の仮面弁士 (3298回)-(2022/02/24(Thu) 18:51:11)
No99239 (nyohhiroki さん) に返信
> DataRow DTRow = DTRowView.Row;
> DataTable DT = (DataTable)this.DGView.DataSource;
> DT.ImportRow(DTRow);

No99235 の dataGridTest と
No99239 の DGView の関係性が今一つ分かりませんが、
DataRowView からの行コピーが目的であれば、 DataSource から辿らずに
 DTRow.Table.ImportRow(DTRow);
という書き方で済ませることもできます。


Table プロパティから辿る方法を使えば、
DataSource が DataTable 以外だった場合にも対応できます。
(DataView や BindingSource がバインドされていた場合など)
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -