Я разрабатываю приложение winforms. У меня есть два представления datagrid, заполненные из двух разных bindingsources (control). Я использую их для реализации подхода мастер-детали. Моя проблема в том, что, когда первое datagridview заполняется с использованием источника привязки, я не могу выбрать первую его строку, потому что первый элемент в источнике привязки выбран по умолчанию и не может быть выбран. Может ли кто-нибудь предоставить мне решение для этогоC# Binding Source Control
ответ
Как вы говорите, первая строка выбрана по умолчанию. Таким образом, после заполнения DataSource для вашего первого GridView вы можете установить второй GridView на основе первой записи. Позже вы проверяете событие SelectionChanged, чтобы заполнить второй GridView, основанный на выбранном Row вашего первого.
Код может выглядеть sth. например:
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 (untested). Лучше использовать первый подход.
UDPATE-2
Я сожалею, чтобы сказать вам, что это не возможно в прекрасной форме. Проблема в том, что Current Property вашего bindingList всегда задается, если ваш DataSource содержит элементы. Таким образом, если пользователь выбирает ту же строку, что и currentSource CurrentSource, ваше событие не будет вызвано. Я нашел решение, которое работает в моем примере. Вам понадобится один gridEvent и, возможно, придется выполнить некоторые улучшения, но идея должна выполнить эту работу. Извините, но без gridEvent Я не могу решить эту проблему:
Обратите внимание, что iam использует List как 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
}
}
Большое вам спасибо. Но моя проблема немного другая. Раньше я пробовал вышеупомянутое решение, это не сработало. Проблема (в моем контексте) связана с источником привязки, если я проверяю dataGridView1.SelectedRows.Count, это показывает 0. Это происходит потому, что, когда мы связываем datagridview с использованием источника привязки, первым элементом в источнике привязки является текущий элемент (в источник связывания). Поэтому после загрузки первого вида gridview я не могу вызвать обработчик события current_changed источника привязки, выбрав первый элемент. В этой форме я хочу использовать события источника привязки. –
@VipinJacob Я обновил свой ответ, чтобы реализовать поведение, используя события и методы bindingSource. – Sebi
он работает, но я не хочу сначала загружать второй datagridveiw.Я просто хочу загрузить первое datagridview, а затем пользователь должен решить, какой выбор будет сделан на первом datagridveiw. И на основе этого выбора необходимо загрузить второе datagridview. И я хочу использовать именно события источника привязки. –
Я не понимаю вашу проблему. Вы хотите выбрать первую строку, но проблема в том, что она выбрана? Уточните, в чем проблема. – Sebi
Я хочу заполнить второй datagridview из выделения, сделанного на первом datagridview. Поэтому, когда первое datagridview заполняется из элемента управления привязкой, я не могу выбрать первую строку в этом datagridview (если я выбираю вторую строку, в которой он работает, я мог бы выбрать строку row после выбора любых других строк) –