DataGridViewがあります。一部のセルは、シリアルポートからデータを受け取ります。データをセルに押し込み、基になるバインドされたオブジェクトを更新します。
私はこのようなことを試みています:
SetValueFromSerial (decimal newValue)
{
dataGridView.CurrentCell.Value = newValue;
}
文字列を使用しても役に立ちません:
dataGridView.CurrentCell.Value = newValue.ToString ();
どちらの場合も、グリッドには何も表示されず、基になる値は変更されていません。
Googleで検索してここで検索しましたが、何も見つかりませんでした。 (何か、おそらく明らかなものを見逃したかもしれませんが、私は完全に怠け者ではありません。)
DataGridView
がデータバインドされている場合、セルのコンテンツを直接変更しないでください。代わりに、データバインドされたオブジェクトを変更する必要があります。 DataBoundItem
のDataGridViewRow
を介してそのオブジェクトにアクセスできます。
MyObject obj = (MyObject)dataGridView.CurrentRow.DataBoundItem;
obj.MyProperty = newValue;
変更がINotifyPropertyChanged
に反映されるように、バインドされたオブジェクトはDataGridView
を実装する必要があることに注意してください。
dataGridView1[1,1].Value="tes";
何らかの理由でデータバインドされたオブジェクトを変更したくない場合(たとえば、グリッドにビューを表示したいが、データソースオブジェクトの一部として表示したくない場合)、これを行うことができます。
1.列を手動で追加:
DataGridViewColumn c = new DataGridViewColumn();
DataGridViewCell cell = new DataGridViewTextBoxCell();
c.CellTemplate = cell;
c.HeaderText = "added";
c.Name = "added";
c.Visible = true;
dgv.Columns.Insert(0, c);
2. DataBindingCompleteイベントで、次のようなことを行います。
foreach (DataGridViewRow row in dgv.Rows)
{if (row.Cells[7].Value.ToString()=="1")
row.Cells[0].Value = "number one"; }
(単なる愚かな例)
ただし、DataBindingCompleteに含まれていることを忘れないでください。そうでない場合、値は空白のままになります
データの更新など、sql-dataadapterで同じ問題が発生しました。
以下は私のためにうまく働いています
mydatgridview.Rows[x].Cells[x].Value="test"
mydatagridview.enabled = false
mydatagridview.enabled = true
新しい行を挿入する方法と、Excelのようにその中のセルの個々の値を設定する方法を探しました。私は次のコードで解決しました:
dataGridView1.ReadOnly = false; //Before modifying, it is required.
dataGridView1.Rows.Add(); //Inserting first row if yet there is no row, first row number is '0'
dataGridView1.Rows[0].Cells[0].Value = "Razib, this is 0,0!"; //Setting the leftmost and topmost cell's value (Not the column header row!)
dataGridView1[1, 0].Value = "This is 0,1!"; //Setting the Second cell of the first row!
注意:
これがあなたの助けになることを願っています。
refresh dataGridViewを覚えていますか?
datagridview.refresh();
この方法を試してください:
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
2回書く必要があります...
私は同じ問題に出くわし、VB.NETで次のように解決しました。 .NET Frameworkなので、適応できるはずです。私のソリューションを比較したかったのですが、今では誰もそれを自分のやり方で解決していないようです。
フィールド宣言を作成します。
Private _currentDataView as DataView
したがって、すべての行をループして、変更したいセルの隣にあることがわかっている値を含むセルを検索するとうまくいきます。
Public Sub SetCellValue(ByVal value As String)
Dim dataView As DataView = _currentDataView
For i As Integer = 0 To dataView.Count - 1
If dataView(i).Row.Item("projID").ToString.Equals("139") Then
dataView(i).Row.Item("Comment") = value
Exit For ' Exit early to save performance
End If
Next
End Sub
あなたがそれをよりよく理解できるように。 ColumnName "projID"が139であることを知っています。それが見つかるまでループし、その後、 "Comment"の "ColumnNameofCell"の値を変更できます。ランタイムに追加されるコメントにこれを使用します。
DataGridView
にDataSource = x
が入力されている(つまり、データバインドされている)場合、DataGridViewセル自体ではなく、バインドされたデータを変更する必要があります。
したがって、既知の行または列からそのデータにアクセスする1つの方法は次のとおりです。
(YourRow.DataBoundItem as DataRowView).Row['YourColumn'] = NewValue;
in VBこれを使用できます
Dim selectedRow As DataRowView
selectedRow = dg.Rows(dg.CurrentCell.RowIndex).DataBoundItem
selectedRow("MyProp") = "myValue"
dg.NotifyCurrentCellDirty(True)
最後の列のsaeed serpooshanに感謝
次の作品。間違っているかもしれませんが、String
値を追加しても、DataGridViewセルと互換性がないようです(ただし、実験もハックも試していません)。
DataGridViewName.Rows[0].Cells[0].Value = 1;
私は多くのメソッドを試しましたが、機能したのはUpdateCellValueだけでした。
dataGridView.Rows[rowIndex].Cells[columnIndex].Value = "New Value";
dataGridView.UpdateCellValue(columnIndex, rowIndex);
私が助けてくれたことを願っています。 =)
private void btn_Addtoreciept_Click(object sender, EventArgs e)
{
serial_number++;
dataGridView_inventory.Rows[serial_number - 1].Cells[0].Value = serial_number;
dataGridView_inventory.Rows[serial_number - 1].Cells[1].Value =comboBox_Reciept_name.Text;
dataGridView_inventory.Rows[serial_number - 1].Cells[2].Value = numericUpDown_recieptprice.Value;
dataGridView_inventory.Rows[serial_number - 1].Cells[3].Value = numericUpDown_Recieptpieces.Value;
dataGridView_inventory.Rows[serial_number - 1].Cells[4].Value = numericUpDown_recieptprice.Value * numericUpDown_Recieptpieces.Value;
numericUpDown_RecieptTotal.Value = serial_number;
}
最初はうまくいきますが、2回目に押すと「インデックスが範囲外でした。コレクションのサイズよりも小さくてはいけません。パラメータ名:インデックス」というエラーが出ますが、セルをクリックすると別の行が表示されますそして、それは次の行で機能し、続けます...
@Thomasが言ったように、変更する要素はINotifyPropertyChangedを実装する必要があります。しかし、データソースも重要です。リストから簡単に作成できるBindingListである必要があります。
ここに私の例があります-データソースは最初にDataTableで、これをListに転送してからBindingListを作成します。次に、BindingSourceを作成し、BindingListをBindingSourceのDataSourceとして使用します。最後に、DataGridViewのDataSourceはこのBindingSourceを使用します。
sp_Select_PersonTableAdapter adapter = new sp_Select_PersonTableAdapter();
DataTable tbl = new DataTable();
tbl.Merge(adapter.GetData());
List<Person> list = tbl.AsEnumerable().Select(x => new Person
{
Id = (Int32) (x["Id"]),
Ime = (string) (x["Name"] ?? ""),
Priimek = (string) (x["LastName"] ?? "")
}).ToList();
BindingList<Person> bindingList = new BindingList<Person>(list);
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = bindingList;
dgvPerson.DataSource = bindingSource;
また、非常に重要なことは、各クラスのメンバーセッターがOnPropertyChanged()を呼び出す必要があることです。それなしでは機能しません。したがって、私のクラスは次のようになります。
public class Person : INotifyPropertyChanged
{
private int _id;
private string _name;
private string _lastName;
public int Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
OnPropertyChanged();
}
}
}
public string Name
{
get { return _name; }
set
{
if (value != _name)
{
_name = value;
OnPropertyChanged();
}
}
}
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName= value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}