C# 绑定源代码管理
C# Binding Source Control
我正在开发 winforms 应用程序。我有两个从两个不同的绑定源(控件)填充的数据网格视图。我正在使用这些来实现主细节方法。我的问题是,当使用绑定源填充第一个 datagridview 时,我不能 select 它的第一行,因为绑定源中的第一个元素默认是 selected 并且不能select编辑。谁能为我提供解决方案
正如您所说,默认情况下第一行是 selected。因此,在将 DataSource 填充到您的第一个 GridView 之后,您可以根据第一个条目设置第二个 GridView。稍后您检查 selectionChanged 事件以根据第一个 GridView 的 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();
模拟对焦第二行直接第一行。有点难看,但我猜这会引发 current_changed(未经测试)。最好使用第一种方法。
UDPATE-2
很遗憾地告诉你,这是不可能的。问题是,如果您的 DataSource 包含项目,则始终设置 bindingList 的 Current 属性。因此,如果用户 select 与 bindingSource Current 属性 相同的行包含您的事件将不会被调用。我找到了一个适用于我的示例的解决方案。您将需要一个 gridEvent 并且可能需要做一些改进,但这个想法应该可以完成工作。抱歉,如果没有 gridEvent,我无法解决这个问题:
请注意,我使用 List 作为我的测试用例的数据源。您有 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
}
}
我正在开发 winforms 应用程序。我有两个从两个不同的绑定源(控件)填充的数据网格视图。我正在使用这些来实现主细节方法。我的问题是,当使用绑定源填充第一个 datagridview 时,我不能 select 它的第一行,因为绑定源中的第一个元素默认是 selected 并且不能select编辑。谁能为我提供解决方案
正如您所说,默认情况下第一行是 selected。因此,在将 DataSource 填充到您的第一个 GridView 之后,您可以根据第一个条目设置第二个 GridView。稍后您检查 selectionChanged 事件以根据第一个 GridView 的 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();
模拟对焦第二行直接第一行。有点难看,但我猜这会引发 current_changed(未经测试)。最好使用第一种方法。
UDPATE-2
很遗憾地告诉你,这是不可能的。问题是,如果您的 DataSource 包含项目,则始终设置 bindingList 的 Current 属性。因此,如果用户 select 与 bindingSource Current 属性 相同的行包含您的事件将不会被调用。我找到了一个适用于我的示例的解决方案。您将需要一个 gridEvent 并且可能需要做一些改进,但这个想法应该可以完成工作。抱歉,如果没有 gridEvent,我无法解决这个问题:
请注意,我使用 List 作为我的测试用例的数据源。您有 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
}
}