Как перейти к последнему нажатию на строку в datagridview

#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:

Этот вопрос, похоже, состоит из двух частей:

  1. Как взаимодействовать между двумя формами Windows
  2. Как изменить выбранную строку в 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;
    } 
}