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