滚动后Datagrid选择了错误的行
Posted
技术标签:
【中文标题】滚动后Datagrid选择了错误的行【英文标题】:Datagrid is selecting the wrong row after scrolling 【发布时间】:2013-04-08 04:02:54 【问题描述】:我在 WinForm 应用程序中有一个绑定到地址列表的数据网格。地址列表很长,所以我必须滚动选择我想要的地址。但是,在我滚动并找到我想要的地址并选择它之后,数据网格将选择第一次加载表单时位于网格上相同位置的地址。我想知道我做错了什么以及如何获得我想要的结果。
//
// bindingSource1
//
private System.Windows.Forms.BindingSource bindingSource1;
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
this.bindingSource1.DataSource = typeof(ViewModels.ListAddressViewModel);
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AllowUserToOrderColumns = true;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[]
this.HouseNumber,
this.Prefix,
this.StreetName,
this.StreetType,
this.StreetSuffix,
this.SecondaryType,
this.SecondaryNumber,
this.City,
this.State,
this.ZipCode);
this.dataGridView1.DataBindings.Add(new System.Windows.Forms.Binding("DataSource", this.bindingSource1, "AddressList", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 50);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dataGridView1.ShowCellErrors = false;
this.dataGridView1.ShowCellToolTips = false;
this.dataGridView1.ShowEditingIcon = false;
this.dataGridView1.ShowRowErrors = false;
this.dataGridView1.Size = new System.Drawing.Size(1014, 421);
this.dataGridView1.TabIndex = 2;
this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged);
//Selection Change Handler
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
if (dataGridView1.SelectedRows.Count > 0)
_vm.SelectedAddress = (Address)dataGridView1.SelectedRows[0].DataBoundItem;
//My View Model (_vm)
public class ListAddressViewModel
public IList<Address> AddressList get; set;
private IAddressRepository _repo;
public Address SelectedAddress get;set;
public ListAddressViewModel()
AddressList = new List<Address>();
public ListAddressViewModel(IAddressRepository AddrRepo)
:this()
_repo = AddrRepo
init();
private void init()
if(_repo != null)
AddressList = _repo.FindAll();
... etc..
【问题讨论】:
您需要记录您的bindingSource1
对象以及_vm
是什么。
添加了 Bindingsource 和 _vm 代码。如您所见,_vm 只是 ViewModel 的简单实现。
如果你能给我们提供一个我们可以玩的源代码会很棒吗?也许这可能是您的程序的一些有限子集,它不会泄露任何专有数据,但内部仍然存在错误?
@Scott:你能分享你绑定对象_vm
和dataGridView1
的代码
【参考方案1】:
这样的……
if (dataGridView1.SelectedRows.Count > 0)
_vm.SelectedAddress =(Address)dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["Address"].Value.ToString();
【讨论】:
【参考方案2】:可能不是一个很有帮助的答案,但我无法复制您的问题。我已经发布了我使用的代码,并且每次都得到了正确的选择。我所做的唯一更改是将 datagridview1.DataSource 更改为 ListAddressViewModel 的实例而不是类型 - 这本身可能无法解决问题,因为它只是我输入数据的一种方式。无论如何,这是我的代码的价值!希望它会帮助别人。 注意我已经注释掉了我在Form代码中进行修改的原始代码。
public class Address
public string AddressLine1 get; set;
public string City get; set;
public string PostCode get; set;
public class ListAddressViewModel
public IList<Address> AddressList get; set;
public Address SelectedAddress get; set;
public ListAddressViewModel()
AddressList = new List<Address>();
init();
private void init()
AddressList = new List<Address>
new Address AddressLine1 = "Address 1", City = "City 1", PostCode = "PostCode 1" ,
new Address AddressLine1 = "Address 2", City = "City 2", PostCode = "PostCode 2" ,
new Address AddressLine1 = "Address 3", City = "City 3", PostCode = "PostCode 3" ,
new Address AddressLine1 = "Address 4", City = "City 4", PostCode = "PostCode 4" ,
new Address AddressLine1 = "Address 5", City = "City 5", PostCode = "PostCode 5" ,
new Address AddressLine1 = "Address 6", City = "City 6", PostCode = "PostCode 6" ,
new Address AddressLine1 = "Address 7", City = "City 7", PostCode = "PostCode 7" ,
new Address AddressLine1 = "Address 8", City = "City 8", PostCode = "PostCode 8" ,
new Address AddressLine1 = "Address 9", City = "City 9", PostCode = "PostCode 9" ,
new Address AddressLine1 = "Address 10", City = "City 10", PostCode = "PostCode 10" ,
new Address AddressLine1 = "Address 11", City = "City 11", PostCode = "PostCode 11" ,
new Address AddressLine1 = "Address 12", City = "City 12", PostCode = "PostCode 12" ,
new Address AddressLine1 = "Address 13", City = "City 13", PostCode = "PostCode 13" ,
new Address AddressLine1 = "Address 14", City = "City 14", PostCode = "PostCode 14" ,
new Address AddressLine1 = "Address 15", City = "City 15", PostCode = "PostCode 15" ,
new Address AddressLine1 = "Address 16", City = "City 16", PostCode = "PostCode 16" ,
new Address AddressLine1 = "Address 17", City = "City 17", PostCode = "PostCode 17" ,
new Address AddressLine1 = "Address 18", City = "City 18", PostCode = "PostCode 18" ,
new Address AddressLine1 = "Address 19", City = "City 19", PostCode = "PostCode 19"
;
public partial class Form3 : Form
private System.Windows.Forms.BindingSource bindingSource1;
private ListAddressViewModel VM get; set;
private DataGridView dataGridView1;
public Form3()
InitializeComponent();
this.dataGridView1 = new DataGridView();
this.VM = new ListAddressViewModel();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
//this.bindingSource1.DataSource = typeof(ListAddressViewModel);
this.bindingSource1.DataSource = this.VM;
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AllowUserToOrderColumns = true;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
//this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[]
// this.AddressLine1,
// this.City,
// this.PostCode);
this.dataGridView1.DataBindings.Add(new System.Windows.Forms.Binding("DataSource", this.bindingSource1, "AddressList", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
//this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
//this.dataGridView1.Location = new System.Drawing.Point(0, 50);
this.dataGridView1.Location = new System.Drawing.Point(33, 27);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dataGridView1.ShowCellErrors = false;
this.dataGridView1.ShowCellToolTips = false;
this.dataGridView1.ShowEditingIcon = false;
this.dataGridView1.ShowRowErrors = false;
//this.dataGridView1.Size = new System.Drawing.Size(1014, 421);
this.dataGridView1.Size = new System.Drawing.Size(345, 150);
this.dataGridView1.TabIndex = 2;
this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged);
this.Controls.Add(this.dataGridView1);
//Selection Change Handler
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
if (dataGridView1.SelectedRows.Count > 0)
var addr = (Address)dataGridView1.SelectedRows[0].DataBoundItem;
var msg = String.Format("0, 1, 2", addr.AddressLine1, addr.City, addr.PostCode);
MessageBox.Show(msg, "Message", MessageBoxButtons.OK);
// _vm.SelectedAddress = (Address)dataGridView1.SelectedRows[0].DataBoundItem;
【讨论】:
【参考方案3】:String AddressLine1 = dataGridView1.SelectedRows[0].Cells[Columnindex].Value.ToString()
String City = dataGridView1.SelectedRows[0].Cells[Columnindex].Value.ToString()
String PostCode = dataGridView1.SelectedRows[0].Cells[Columnindex].Value.ToString()
【讨论】:
【参考方案4】:尝试使用行的选定索引,而不是选定的行集合。由于网格的虚拟化,我在使用 Telerik 的 gridview 时遇到了问题。
有很多方法可以使用被选中的当前行的索引,但这里还有另一种方法。
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
//e holds column and row index's selected
我不能多说,因为我不知道你的代码的全部范围。
【讨论】:
以上是关于滚动后Datagrid选择了错误的行的主要内容,如果未能解决你的问题,请参考以下文章
easyui datagrid怎么可以移除多行呢, 请教高手
jquery easyui datagrid 在翻页以后仍能记录被选中的行及刷新设置选中行数据
我想更改DataGrid选定的行高,而DataGrid中的数据保持不变
如何根据驻留在 updatePanel 中的 DataGrid 中所做的行选择来更新控件 [DataGrid、TextBoxes 和标签]?