DataGridView: Сохраните выборы после того, как источник данных будет изменен?

Существует ли способ сохранить выбранные ячейки DataGridView выбранными после того, как DataSource будет изменен?

5
задан Y_Y 31 December 2009 в 22:46
поделиться

1 ответ

Вы можете сопоставить то, что должно быть выбрано на основе критериев, специфичных для ваших нужд, и просто установить свойство Select либо ячейки, либо строки в true/false в зависимости от вашего соответствия. Вот простой пример, который вы можете привести во вновь созданный проект winforms, который проиллюстрирует суть проблемы. Чтобы этот пример заработал, убедитесь, что вы установили свойство SelectionMode в DataGridView = FullRowSelect. Если вы хотите сохранить/применить выделение ячеек, подход будет аналогичным. Обратите внимание: вы также можете просто сохранить список выбранных индексов строк, но это обычно не имеет смысла при загрузке другого источника данных, так как обычно небезопасно, что будет какое-либо соответствие между реальными строками и их физическим положением в данных.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace DataGridViewRetainSelection
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private readonly List<Person> currentPeople = new List<Person>();
        private bool dummyToggle = true;

        private void Form1_Load(object sender, EventArgs e)
        {
            SwitchDataSource(); // will just new up the datasource
        }

        private void ButtonSwitchDataSourceClick(object sender, EventArgs e)
        {
            SwitchDataSource();
        }

        private void SwitchDataSource()
        {
            var selectedPeople = (from DataGridViewRow row in dataGridViewPeople.Rows where row.Selected select currentPeople[row.Index]).ToList();

            peopleBindingSource.DataSource = null;

            currentPeople.Clear();
            if (dummyToggle)
            {
                currentPeople.Add(new Person { Name = "Joel Spolsky" });
                currentPeople.Add(new Person { Name = "Jeff Atwood" });
                currentPeople.Add(new Person { Name = "Jarrod Dixon" });
                currentPeople.Add(new Person { Name = "Geoff Dalgas" });
                currentPeople.Add(new Person { Name = "Brent Ozar" });
            }
            else
            {
                currentPeople.Add(new Person { Name = "Joel Spolsky" });
                currentPeople.Add(new Person { Name = "Jeff Atwood" });
                currentPeople.Add(new Person { Name = "Brent Ozar" });
            }

            dummyToggle = !dummyToggle;

            peopleBindingSource.DataSource = currentPeople;

            foreach (var person in selectedPeople)
            {
                foreach (DataGridViewRow row in dataGridViewPeople.Rows)
                {
                    if (string.Equals(row.Cells[0].Value, person.Name))
                    {
                        row.Selected = true;
                    }
                }
            }
        }
    }

    public sealed class Person
    {
        public string Name { get; set; }
    }

}

Для реализации той же самой функциональности для выбранных ячеек сделайте что-то вроде следующего. Я оставляю предыдущий код, если он кому-то понадобится. Обратите внимание: здесь я просто использую анонимный тип, возможно, вам понадобится что-то более сложное в зависимости от полей членов, свойств и т.д., но общий принцип настройки выбранных ячеек правильно проиллюстрирован и может быть легко протестирован и отлажен для понимания, я надеюсь.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace DataGridViewRetainSelection
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private readonly List<Person> currentPeople = new List<Person>();
        private bool dummyToggle = true;

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridViewPeople.SelectionMode = DataGridViewSelectionMode.CellSelect;
            SwitchDataSource(); // will just new up the datasource
        }

        private void ButtonSwitchDataSourceClick(object sender, EventArgs e)
        {
            SwitchDataSource();
        }

        private void SwitchDataSource()
        {
            var selectedPeopleAndCells = (from DataGridViewCell cell in dataGridViewPeople.SelectedCells where cell.Selected select new { Person = currentPeople[cell.RowIndex], Cell = cell }).ToList();

            peopleBindingSource.DataSource = null;

            currentPeople.Clear();
            if (dummyToggle)
            {
                currentPeople.Add(new Person { Name = "Joel Spolsky", Id = 0 });
                currentPeople.Add(new Person { Name = "Jeff Atwood", Id = 1 });
                currentPeople.Add(new Person { Name = "Jarrod Dixon", Id = 2 });
                currentPeople.Add(new Person { Name = "Geoff Dalgas", Id = 3 });
                currentPeople.Add(new Person { Name = "Brent Ozar", Id = 4 });
            }
            else
            {
                currentPeople.Add(new Person { Name = "Joel Spolsky", Id = 0 });
                currentPeople.Add(new Person { Name = "Jeff Atwood", Id = 1 });
                currentPeople.Add(new Person { Name = "Brent Ozar", Id = 4 });
            }

            dummyToggle = !dummyToggle;

            peopleBindingSource.DataSource = currentPeople;

            foreach (var personAndCell in selectedPeopleAndCells)
            {
                foreach (DataGridViewRow row in dataGridViewPeople.Rows)
                {
                    if (string.Equals(row.Cells[0].Value, personAndCell.Person.Id))
                    {
                        row.Cells[personAndCell.Cell.ColumnIndex].Selected = true;
                    }
                }
            }
        }
    }

    public sealed class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

}
5
ответ дан 14 December 2019 в 19:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: