C#绑定源控件

时间:2016-12-14 10:03:51

标签: c# winforms datagridview bindingsource

我正在开发一个winforms应用程序。我有两个数据网格视图从两个不同的绑定源(控件)填充。我正在使用它们来实现主细节方法。我的问题是,当使用绑定源填充第一个datagridview时,我无法选择它的第一行,因为绑定源中的第一个元素是默认选择的,无法选择。任何人都可以为我提供解决方案

1 个答案:

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