#c# #winforms #datagridview
#c# #winforms #datagridview
Вопрос:
Следующий код используется для заполнения DGV:
private void frmSwitch_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'newCityCollectionDataSet.PropertyInformation' table. You can move, or remove it, as needed.
this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
// TODO: This line of code loads data into the 'newCityCollectionDataSet.ClientTable' table. You can move, or remove it, as needed.
this.clientTableTableAdapter.Fill(this.newCityCollectionDataSet.ClientTable);
}
Этот код позволяет мне передавать необходимую информацию в «сводную форму»:
private void propertyInformationDataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
System.Data.DataRowView SelectedRowView;
newCityCollectionDataSet.PropertyInformationRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
frmSummary SummaryForm = new frmSummary(this);
SummaryForm.LoadCaseNumberKey(SelectedRow.CaseNumberKey, true, null);
SummaryForm.LoadBRTNumberKey(SelectedRow.BRTNumber, null);
SummaryForm.Show();
}
Что я хочу сделать, так это передать выбранную строку и добавить 1, чтобы перейти к следующей строке, если текущая выбранная строка больше не действительна (например, когда в «сводной форме» установлен флажок FileFinishedCheckBox). Я также хочу, чтобы то же самое происходило всякий раз, когда в DataGridView установлен флажок, чтобы людям не приходилось прокручивать назад к файлу, над которым они работают.
Код, который выполняет обновление при необходимости, выглядит следующим образом:
public void PerformRefresh()
{
this.propertyInformationBindingSource.EndEdit();
this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
this.propertyInformationDataGridView.Refresh();
}
Любая помощь была бы отличной.
Комментарии:
1. Извините, я не понимаю смысла. У меня даже нет разумного вопроса, который я мог бы задать, поскольку я абсолютно не понимаю, какова ваша цель. Не могли бы вы уточнить?
2. Когда я дважды щелкаю по записи в DGV, появляется окно с записью. На этом экране есть флажок, который при нажатии закрывает запись. DGV должен отражать это при закрытии окна, а затем прокручивать обратно в ту же область, чтобы можно было выбрать следующую запись без необходимости прокрутки вниз до этой области. Например, выбрана запись 456 из 1000. Пользователь закрывает эту запись и закрывает окно. Я хочу, чтобы DGV обновился, что исключит эту запись из текущего запроса и перейдет к представлению, в котором будет запись 455,457,458,459 и т.д.
3. Другой способ решить эту проблему — установить флажок в DGV, а не в форме. Проблема, с которой я сталкиваюсь, заключается в том, что я понятия не имею, как использовать флажок в DGV для передачи значений в отдельную таблицу (Т.Е. Как вы используете события в столбце DGV?). Мне нужно передать значения в таблицу, которую извлекает служба Windows на сервере для отправки отчетов нашим клиентам.
Ответ №1:
Этот вопрос, похоже, состоит из двух частей:
- Как взаимодействовать между двумя формами Windows
- Как изменить выбранную строку в datagridview
Существует много разных способов решения обеих задач, поэтому я просто приведу вам два, которые будут работать. Первый (для Windows forms) является самым простым, в то время как второй (для изменения выбранной строки), на мой взгляд, является правильным методом.
Связь между Windows forms
Самый простой способ взаимодействия между двумя формами Windows — передать ссылку на одну форму в другую форму.
Итак, скажем, у вас есть Form1, который открывает Form2, вы могли бы сделать что-то вроде этого:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 f = new Form2(this);
f.Show();
}
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
}
public partial class Form2 : Form
{
private Form1 _parentForm;
public Form2(Form1 parentForm)
{
InitializeComponent();
_parentForm = parentForm;
_parentForm.ShowMessage("I am a message from form1);
}
}
Итак, в вашем примере вы должны добавить метод в родительскую форму, который принимает в качестве своего параметра уникальное значение для строки, выбранной в dgv3, для отображения в gdv1. В методе (который является членом родительской формы, вы вводите код центрирования, который я покажу ниже).
Другие способы сделать это включают передачу делегата дочерней форме, которая является методом центрирования datagridview. Это имеет то преимущество, что вы больше не привязаны к постоянной передаче в Form1 и даже можете предоставлять различные действия в соответствии с флажком, но их немного сложнее реализовать.
Центрирование по выбранной записи в DataGridView
Мой предпочтительный способ сделать это — использовать bindingsource для предоставления источника данных для сетки. Вы также можете напрямую получить доступ к позиции сетки, используя свойство CurrentCell, но с помощью bindingsource вы получаете немного больше прибыли.
В приведенном ниже коде у нас есть форма, которая создает BindingSource, присваивает его источнику данных значение BindingList типа MyBindingList, а затем устанавливает источник привязки в качестве источника данных DataGridView.
Объекты в списке привязок имеют уникальное свойство «PrimaryKey», позволяющее нам их находить.
Затем я показываю код центрирования, который на самом деле очень прост.
Сначала мы получаем индекс в источнике привязки нужного вам, вызывая Find()
метод источника привязки.
Во-вторых, мы меняем положение источников привязки (это также обновляет отображение datagridview).
Наконец, мы изменяем FirstDisplayedScrollingRowIndex datagridview так, чтобы выбранная строка не находилась в самом верху или внизу сетки (вы захотите добавить проверку, чтобы убедиться, что это допустимый индекс, если вы используете эту строку).
public partial class Form1 : Form
{
BindingSource bs;
public Form1()
{
InitializeComponent();
bs = new BindingSource();
MyBindingList<BackingObject> backing_objects = new MyBindingList<BackingObject>();
backing_objects.Add(new BackingObject{ PrimaryKey = 1, Name = "Fred", Hidden = "Fred 1"});
bs.DataSource = backing_objects;
dataGridView1.DataSource = bs;
}
private void button1_Click(object sender, EventArgs e)
{
int index = bs.Find("PrimaryKey", 5);
bs.Position = index;
dataGridView1.FirstDisplayedScrollingRowIndex = index - 1;
}
}
Теперь последнее, что нужно отметить, это то, что bindinglist из коробки не поддерживает Find()
метод bindingsource . Вот почему я использую свой пользовательский MyBindingList. Код для реализации этого можно найти здесь .
По сути, вам нужен класс, подобный следующему:
public class MyBindingList<T> : BindingList<T>
{
protected override bool SupportsSearchingCore
{
get
{
return true;
}
}
protected override int FindCore(PropertyDescriptor prop, object key)
{
// Get the property info for the specified property.
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;
if (key != null)
{
// Loop through the items to see if the key
// value matches the property value.
for (int i = 0; i < Count; i)
{
item = (T)Items[i];
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}
}