
C# WinForm のDataGridView CellValueChangeイベントが発火する条件について、ユーザーがセルを操作して値を変更した場合は当然の事で、プログラム内部でDataGridViewCellの値を編集した場合も同様です。しかし、データソースにDataTableをバインドし、DataTableの値を変えても発火してくれませんでした。(セルの値ら追従して変わってぬれる)データソースを変更した際にもCellValueChangeのイベントを発火させる方法はないでしょうか。CellValueChangeを使う事にこだわりはありませんが、実現したい事としましては、DataTableで変更された対象セルの背景色を変えたいになります。どうぞ宜しくお願い致します。
No.3ベストアンサー
- 回答日時:
ANo.2です。
文字数が足らなくなったので連投します。
DataTableを利用している場合、DataTableのイベントで捕捉して制御することが可能かと思います。
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private BindingSource bindingSource;
private DataTable dataList;
public Form1()
{
InitializeComponent();
dataList = new DataTable();
dataList.Columns.AddRange(new DataColumn[] { new DataColumn("Column1"), new DataColumn("Column2") });
var row = dataList.NewRow();
row["Column1"] = "aaa";
row["Column2"] = "aaaa";
dataList.Rows.Add(row);
row = dataList.NewRow();
row["Column1"] = "bbb";
row["Column2"] = "bbbb";
dataList.Rows.Add(row);
row = dataList.NewRow();
row["Column1"] = "ccc";
row["Column2"] = "cccc";
dataList.Rows.Add(row);
dataList.ColumnChanged += (sender, e) =>
{
var rowIndex = dataList.Rows.IndexOf(e.Row);
rowIndex = rowIndex == -1 ? dataList.Rows.Count : rowIndex;
dgv.Rows[rowIndex].Cells[e.Column.ColumnName].Style.BackColor = Color.Red;
};
bindingSource = new BindingSource();
bindingSource.DataSource = dataList;
dgv.DataSource = bindingSource;
}
private void datachangeButton_Click(object sender, EventArgs e)
{
dataList.Rows[2]["Column2"] = "dddd";
dgv.Refresh();
}
}
}
コードまで載せて下さりありがとうございます。
BaindingListの方とても参考になりました。今回はDataTableを利用するやり方にしたいと思います。やはりDataGridViewとDataTableの整合は行列でやるしかないんですね。DataGridViewでソートやフィルターをすると整合が取れなくなるので上手いこと実装したいと思いますが、その他注意点などありましたらご教授頂けると幸いです。ほぼベストアンサーに近い回答ですが、あと数日待ってからにさせて下さい。
No.2
- 回答日時:
> BindingSourceのデータソースから取り出したDataTableに変更を加わえ
> ると、イベントが発火してくれるという理解で良いでしょうか?
CellValueChangeイベントが発火するかという問いならば違います。
CellValueChangeイベントはあくまでDataGridViewオブジェクトを操作した時に発生するイベントであり、データが変更されたからといって発生するものではありません。
BindingSource、BindingList、INotifyPropertyChangedを利用して値変更の通知をうけてBindingListオブジェクトのイベントを発火させ、何が通知されたかによって制御することで実装することができます。
ただし、下記の点を考慮する必要があります。
まず、データとDataGridViewは別物であるということ。
データの変更通知としては、DataGridViewのどのセルが変わったかなんてどうもいいことなので、DataGridViewのどのセル、という判断は独自で実装する必要があります。
次に、BindingList<T>などに依存すること。
DataSet、DataTableの結果を丸々DataSourceとして設定して、DataRowStateなどを利用して変更された行かどうかなどの判定を行う実装をしている場合、適合することはできません。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private BindingSource bindingSource;
private BindingList<Data> dataList;
public Form1()
{
InitializeComponent();
dataList = new BindingList<Data>()
{
new Data() { Column1 = "aaa", Column2 = "aaaa"},
new Data() { Column1 = "bbb", Column2 = "bbbb"},
new Data() { Column1 = "ccc", Column2 = "cccc"}
};
dataList.ListChanged += (sender, e) =>
{
if (e.ListChangedType != ListChangedType.ItemChanged)
{
return;
}
if (e.PropertyDescriptor.Name == "Column2")
{
dgv.Rows[e.NewIndex].Cells[1].Style.BackColor = Color.Red;
}
};
bindingSource = new BindingSource();
bindingSource.DataSource = dataList;
dgv.DataSource = bindingSource;
}
private void datachangeButton_Click(object sender, EventArgs e)
{
dataList[2].Column2 = "dddd";
dgv.Refresh();
}
}
class Data : INotifyPropertyChanged
{
private string column1 = string.Empty;
private string column2 = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Column1
{
get
{
return this.column1;
}
set
{
if (value != this.column1)
{
this.column1 = value;
NotifyPropertyChanged();
}
}
}
public string Column2
{
get
{
return this.column2;
}
set
{
if (value != this.column2)
{
this.column2 = value;
NotifyPropertyChanged();
}
}
}
}
}
No.1
- 回答日時:
値を変更してもDataGridViewオブジェクトの操作による変更ではないので、イベントは発火しません。
BindingSourceを介したバインドを検討してみてください。
https://docs.microsoft.com/ja-jp/dotnet/api/syst …
ご回答ありがとうございます。BindingSourceのデータソースから取り出したDataTableに変更を加わえると、イベントが発火してくれるという理解で良いでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) マクロ実行時、自動で背景色を変えたい。 C列にあるチェックボックスをチェックするとB列に「TRUE」 4 2022/11/08 11:14
- Excel(エクセル) マクロ、条件付き書式のfont.color 1 2023/03/28 01:10
- Visual Basic(VBA) VB DataGridViewについて 3 2022/06/08 17:20
- Excel(エクセル) エクセルの表示形式について教えてください あるセルの「A」という値と、別のセルの「B」という値を組み 4 2023/02/21 21:55
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 3 2022/06/10 09:24
- Excel(エクセル) エクセルのマクロについて教えてください。 1 2023/01/20 16:37
- その他(Microsoft Office) Excelの条件付き書式についての質問です。 2 2022/09/08 01:25
- Excel(エクセル) エクセルVBA、ファイル名をセルの値で保存の方法を教えてください。 おそれいります。こちらで数々のエ 6 2023/06/30 22:17
- Excel(エクセル) エクセルのマクロについて教えてください。 7 2023/01/13 13:33
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Swingで印刷
-
SortedSetならぬSortedListの良...
-
「Util.Timer」を使って車輪が...
-
落下する正方形を左右に移動す...
-
Java 他クラスの呼び出しが上手...
-
struts2のchainで値の受け渡し...
-
決められて時間が経過するとア...
-
長方形を描いて、それを移動さ...
-
JavaFXでの表内のチェックボッ...
-
C# visibleプロパティをfalseに...
-
C#でキーイベントが発生しない...
-
C#でのWNetAddConnection3の使...
-
setIcon() の反対のようなもの...
-
エンターキーを押すとOKボタン...
-
リストボックスの選択項目をさ...
-
Thread.sleepのInterruptedExce...
-
Graphicsクラスを使って描画履...
-
swing初心者です
-
JPanel上のマウスの座標の取得
-
JScrollPaneで、表示がおかしく...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
大量のデータを読み込んで表示...
-
C#で、あるクラスのメンバーす...
-
C# visibleプロパティをfalseに...
-
C#でのWNetAddConnection3の使...
-
C# DataGridView列カスタマイズ
-
C# MouseHoverを何度も呼ぶには
-
C#でキーイベントが発生しない...
-
Junitテストでvoid戻り値メッソ...
-
C# WinForm のDataGridView Cel...
-
ボタンの複数割り当てについて
-
ユーザーコントロールを動的に...
-
ボタンのイベントで異なるウィ...
-
LVM_SETITEMSTATEでListViewの...
-
c# スレッド間でのデータの共有
-
C#,listBoxのItem追加について...
-
unityでのC++エラーの原因がわ...
-
C# 矢印キーの取得
-
JavaFXでの表内のチェックボッ...
-
C# 半角カナの文字化けについて
-
C#で別のFormへ複数の値を返そ...
おすすめ情報