2009-10-04 46 views
30

Tôi có một DataGridView. Một số tế bào nhận dữ liệu của chúng từ cổng nối tiếp: Tôi muốn đẩy dữ liệu vào trong ô và cập nhật đối tượng liên kết bên dưới.Làm thế nào để đặt giá trị ô theo chương trình trong DataGridView?

Tôi đang cố gắng một cái gì đó như thế này:

SetValueFromSerial (decimal newValue) 
{ 
    dataGridView.CurrentCell.Value = newValue; 
} 

sử dụng một chuỗi không giúp:

dataGridView.CurrentCell.Value = newValue.ToString(); 

Trong cả hai trường hợp, tôi không thấy bất cứ điều gì trong lưới, và giá trị cơ bản là không thay đổi.

Tôi đã làm Google và tìm kiếm ở đây, nhưng tôi không tìm thấy bất cứ điều gì. (Tôi có thể đã bỏ lỡ điều gì đó, có lẽ là điều gì đó hiển nhiên, nhưng tôi không phải là hoàn toàn lười biếng.)

+2

Gọi 'grid1.NotifyCurrentCellDirty (true);' sau khi sửa đổi 'cell.Value' –

+1

' dataGridView.CurrentCell.Value = newValue.ToString(); dataGridView.editingControl.Text = newValue.ToString(); 'nếu bạn làm điều này bạn có thể thấy những thay đổi ngay lập tức. –

Trả lời

32

Nếu DataGridView là dữ liệu, bạn không nên sửa đổi trực tiếp nội dung của ô. Thay vào đó, bạn nên sửa đổi đối tượng databound. Bạn có thể truy cập vào đối tượng mà thông qua DataBoundItem của DataGridViewRow:

MyObject obj = (MyObject)dataGridView.CurrentRow.DataBoundItem; 
obj.MyProperty = newValue; 

Lưu ý rằng đối tượng bị ràng buộc nên thực hiện INotifyPropertyChanged để các thay đổi được phản ánh trong DataGridView

+0

Tôi đoán cách duy nhất để làm việc này là sử dụng Danh sách làm nguồn dữ liệu? Điều này có lẽ sẽ không làm việc với DataTable như nguồn dữ liệu? Vì vậy, chúng ta cần một số ORM? – FrenkyB

+1

@ user867703, không nhất thiết phải là Danh sách , mọi bộ sưu tập đều hoạt động. Nếu nguồn là một DataTable, kiểu DataBoundItem sẽ là DataRowView. –

+0

một cách đơn giản cũng đang gọi 'grid1.NotifyCurrentCellDirty (true);' sau khi sửa đổi 'cell.Value' –

4

Bạn có nhớ refresh dataGridView không?

datagridview.refresh(); 
+5

Điều này không làm cho DGV làm mới dữ liệu, nó chỉ bắt buộc vẽ lại ... –

27
dataGridView1[1,1].Value="tes"; 
4

tôi đã cùng một vấn đề với sql-dataadapter để cập nhật dữ liệu và như vậy, trên

cách sau đang làm việc cho tôi tốt

mydatgridview.Rows[x].Cells[x].Value="test" 
mydatagridview.enabled = false 
mydatagridview.enabled = true 
5

Nếu bạn không muốn sửa đổi đối tượng dữ liệu từ một số lý do (ví dụ bạn muốn hiển thị một số dạng xem trong lưới của mình, nhưng bạn không muốn nó như là một phần của đối tượng nguồn dữ liệu), bạn có thể muốn làm điều này:

1.Add cột bằng tay:

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.In sự kiện DataBindingComplete làm điều gì đó như thế này:

foreach (DataGridViewRow row in dgv.Rows) 
{if (row.Cells[7].Value.ToString()=="1") 
row.Cells[0].Value = "number one"; } 

(chỉ là một st Ví dụ upid)

nhưng hãy nhớ nó phải được trong DataBindingComplete, nếu không giá trị sẽ vẫn trống

1

Các công trình sau đây. Tôi có thể nhầm lẫn nhưng thêm một giá trị String dường như không tương thích với một ô DataGridView (tôi đã không thử nghiệm hoặc thử bất kỳ hack nào).

DataGridViewName.Rows[0].Cells[0].Value = 1; 
0

Cũng giống như @Thomas cho biết, phần tử bạn muốn thay đổi phải triển khai INotifyPropertyChanged. Nhưng, nguồn dữ liệu cũng rất quan trọng. Nó phải là BindingList, mà bạn có thể tạo dễ dàng từ Danh sách.

Đây là ví dụ của tôi - nguồn dữ liệu ở DataTable đầu tiên, mà tôi chuyển sang Danh sách rồi tạo BindingList. Sau đó, tôi tạo BindingSource và sử dụng BindingList làm DataSource từ BindingSource. Cuối cùng, DataSource từ DataGridView sử dụng BindingSource này.

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; 

Điều gì cũng rất quan trọng: mỗi thành viên của lớp phải gọi OnPropertyChanged(). Nếu không có điều đó, nó sẽ không hoạt động. Vì vậy, lớp học của tôi trông như thế này:

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)); 
     } 

    } 

Thông tin thêm về chủ đề này: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

0
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; 
} 

trên lần đầu tiên nó suôn sẻ nhưng nhấn lần thứ 2 nó mang lại cho tôi lỗi "Index đã ra khỏi phạm vi. Phải là số âm và nhỏ hơn kích thước của bộ sưu tập Tên thông số: chỉ mục "nhưng khi tôi nhấp vào ô khác, một hàng khác xuất hiện và sau đó nó hoạt động cho hàng tiếp theo, và tiếp tục ...

3

I tìm kiếm giải pháp cách tôi c chèn một hàng mới và Cách đặt các giá trị riêng lẻ của các ô bên trong nó như Excel. Tôi giải quyết với đoạn mã sau:

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! 

Lưu ý:

  1. Trước đây tôi đã thiết kế các cột trong chế độ thiết kế.
  2. Tôi đã đặt hiển thị tiêu đề hàng thành false từ thuộc tính của chế độ xem dữ liệu.
  3. Dòng cuối cùng quan trọng cần hiểu: Khi yoou trực tiếp đưa chỉ mục của datagridview, số đầu tiên là số ô, số thứ hai là số hàng! Hãy nhớ nó!

Hy vọng điều này có thể giúp bạn.

1

Nếu DataGridView đã được dân cư bởi DataSource = x (ví dụ là databound) thì bạn cần phải thay đổi dữ liệu ràng buộc, không phải là tế bào DataGridView mình.

Một cách để nhận dữ liệu đó từ một hàng biết hoặc cột là như sau:

(YourRow.DataBoundItem as DataRowView).Row['YourColumn'] = NewValue; 
3

Hãy thử cách này:

dataGridView.CurrentCell.Value = newValue; 

dataGridView.EndEdit(); 

dataGridView.CurrentCell.Value = newValue; 

dataGridView.EndEdit(); 

Cần phải viết hai lần ...

+2

Vui lòng giải thích lý do tại sao các câu lệnh cần phải được viết hai lần? – Abbas

1

Tôi đi qua cùng một vấn đề và giải quyết nó như sau cho VB.NET. Đó là .NET Framework để bạn có thể thích nghi. Muốn so sánh giải pháp của tôi và bây giờ tôi thấy rằng không ai có vẻ giải quyết nó theo cách của tôi.

Thực hiện khai báo trường.

Private _currentDataView as DataView

Vì vậy vòng lặp qua tất cả các hàng và tìm kiếm một ô chứa một giá trị mà tôi biết là bên cạnh các tế bào Tôi muốn thay đổi công việc cho tôi.

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 

Để bạn có thể hiểu rõ hơn. Tôi biết rằng ColumnName "projID" là 139. Tôi lặp lại cho đến khi tôi tìm thấy nó và sau đó tôi có thể thay đổi giá trị của "ColumnNameofCell" trong trường hợp "Comment" của tôi. Tôi sử dụng điều này cho các ý kiến ​​được thêm vào thời gian chạy.

dataview

0

trong VB bạn có thể sử dụng một

Dim selectedRow As DataRowView 
selectedRow = dg.Rows(dg.CurrentCell.RowIndex).DataBoundItem 
selectedRow("MyProp") = "myValue" 
dg.NotifyCurrentCellDirty(True) 

nhờ saeed serpooshan cho hàng cuối cùng

1

tôi đã cố gắng rất nhiều phương pháp, và là người duy nhất mà làm việc là UpdateCellValue:

dataGridView.Rows[rowIndex].Cells[columnIndex].Value = "New Value"; 
dataGridView.UpdateCellValue(columnIndex, rowIndex); 

Tôi hy vọng sẽ hữu ích. =)

Các vấn đề liên quan