我正在开发一个winforms应用程序。我有两个数据网格视图从两个不同的绑定源(控件)填充。我正在使用它们来实现主细节方法。我的问题是,当使用绑定源填充第一个datagridview时,我无法选择它的第一行,因为绑定源中的第一个元素是默认选择的,无法选择。任何人都可以为我提供解决方案
答案 0 :(得分:1)
正如您所说,默认选择第一行。因此,在将DataSource填充到第一个GridView之后,您可以基于第一个条目设置第二个GridView。稍后你检查selectionChanged事件,根据你第一个的selectedRow填充第二个GridView。
代码看起来很......像这样:
private void PopulateDataSource()
{
dataGridView1.DataSource = myBindingSource;
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
如果这不起作用,请告诉我,但应该做好。
<强> UDPATE 强>
以下是使用bindingSource的事件和方法的类似示例:
private void Initialize()
{
RegisterBindingSourceEvents();
dataGridView1.DataSource = bindingSource1;
dataGridView2.DataSource = bindingSource2;
bindingSource1.DataSource = myDataSource;
}
private void RegisterBindingSourceEvents()
{
bindingSource1.DataSourceChanged += BindingSource1_DataSourceChanged;
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
private void BindingSource1_DataSourceChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
此外,您可以使用:
bindingSource.MoveNext();
bindingSource.MoveFirst();
模拟聚焦seconde行和直接第一行。有点难看,但我猜这会引发current_changed(未经测试)。更好地使用第一种方法。
<强> UDPATE-2 强>
我很抱歉地告诉你,这是不可能以美丽的方式。问题是如果您的DataSource包含项目,则始终设置bindingList的Current属性。因此,如果用户选择与bindingSource当前属性包含相同的行,则您的事件不会被调用。我找到了一个适用于我的例子的解决方案。你需要一个gridEvent,也许还需要做一些改进,但这个想法应该可以完成。抱歉,但没有gridEvent,我无法解决这个问题:请注意,iam使用List作为我的Testcase的DataSource。您有DataTable并且必须转换为DataRowView而不是Dummy。
private bool _automatedRowChange;
private void Initialize()
{
List<Dummy> dummies = new List<Dummy> { new Dummy { Id = 1, Text = "Test1" }, new Dummy { Id = 2, Text = "Test2" } };
bindingSource1.DataSource = dummies;
dataGridView1.DataSource = bindingSource1;
//So the first row isn't focused but the bindingSource Current Property still holds the first entry
//That's why it won't fire currentChange even if you click the first row. Just looks better for the user i guess
dataGridView1.ClearSelection();
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
dataGridView1.CellClick += DataGridView1_CellClick;
}
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
var clickedRow = dataGridView1.Rows[e.RowIndex].DataBoundItem as Dummy;
var currentRow = bindingSource1.Current as Dummy;
if (clickedRow != null &&
currentRow != null &&
clickedRow.Equals(currentRow))
{
_automatedRowChange = true;
bindingSource1.MoveNext();
_automatedRowChange = false; //MovePrevious is based on the click and should load the dataSource2
bindingSource1.MovePrevious();
}
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
if (!_automatedRowChange) //Check if you jump to next item automatically so you don't load dataSource2 in this case
{
//Set the second DataSource based on selectedRow
}
}