Создание таблицы данных из выбранных DataGridViews ячеек c#

#c# #list #winforms #datatable #datagridview

#c# #Список #winforms #таблица данных #datagridview

Вопрос:

Я нашел get datatable из «выбранных строк», но не смог найти из «выбранных ячеек». Мне нужна помощь для этого.

Чтобы решить эту проблему, я составил два списка из выбранных ячеек. Эти два списка содержат номера индексов столбцов и индексов строк, как вы видите ниже. Есть ли какой-либо способ получить datatable из этих списков? Если нет, не могли бы вы дать мне какие-либо другие решения?

Индекс столбца список индексов строк:

  List<int> cols = dgv.SelectedCells.Cast<DataGridViewCell>().Select(x => x.ColumnIndex).Distinct().ToList();
 List<int> rows = dgv.SelectedCells.Cast<DataGridViewCell>().Select(x => x.RowIndex).Distinct().ToList();
 

введите описание изображения здесь

Ответ №1:

Вероятно, здесь не важно знать или различать индексы;

DataGridViewCell сможет ссылаться на его OwnerColumn и OwnerRow , который будет содержать не только Index свойство, но также информацию о типе и имя.

Я собираюсь предоставить метод расширения ( GetDataTable ), который демонстрирует генерацию DataTable имени "SelectedCell" .

Сначала он гарантирует, что столбцы будут добавлены в новый DataTable экземпляр, поскольку это определит поля, используемые строками. При создании строк в новом DataTable мы будем условно перебирать исходные cells (полагаясь на уникальные имена столбцов повсюду) и SetField .

 public static class DataGridViewExtension
{

    public static DataTable GetDataTable(this DataGridViewSelectedCellCollection cellCollection)
    {
        var cells = cellCollection.Cast<DataGridViewCell>()
            .OrderBy(item => item.RowIndex)
            .ThenBy(item => item.ColumnIndex);

        var cellTuples = cells.Select(c => (c.OwningRow, c.OwningColumn, c.Value)).ToArray();
        var distinctColumns = cellTuples.Select(c => c.OwningColumn).Distinct();
        var distinctRows = cellTuples.Select(c => c.OwningRow).Distinct();

        var dt = new DataTable("SelectedCell");

        foreach (var col in distinctColumns)
        {
            // if selected cells are jagged, we may have to add support for, or specify, nullable types of column value type.
            dt.Columns.Add(col.Name, col.ValueType ?? typeof(object));
        }

        foreach (var row in distinctRows)
        {
            var newRow = dt.NewRow();                
            foreach (var (_, OwningColumn, Value) in cellTuples.Where(item => item.OwningRow == row))
            {
                newRow.SetField(OwningColumn.Name, Value);
            }
            dt.Rows.Add(newRow);
        }

        return dt;
    }

    public static IDataReader GetDataReader(this DataGridViewSelectedCellCollection collection)
    {
        var dt = collection.GetDataTable();           
        return new DataTableReader(dt);
    }
}
 

Для тестирования вот фрагмент, в котором я создал Form и добавил 2 DataGridView элемента управления.

 public Form1()
{
    dataGridView1.SelectionChanged  = DataGridView1_SelectionChanged;
}

private void DataGridView1_SelectionChanged(object sender, EventArgs e)
{
    var dt = dataGridView1.SelectedCells.GetDataTable();
    dataGridView2.ClearSelection();
    dataGridView2.DataSource = null;
    dataGridView2.DataSource = dt;
    //var dataReader = dataGridView1.SelectedCells.GetDataReader();
    //var odt = new DataTable("OtherSelectedCells");
    //odt.Load(dataReader);
}
 

Фрагмент формы с DataGridView

Как вы можете видеть, необходимо учитывать и обрабатывать поведение элементов управления, в том числе:

  • выбор, когда элементы управления ячейками находятся в состоянии редактирования.
  • сортировка, когда выборки не являются однородными.
  • обработка типа столбца ячейки

Комментарии:

1. Спасибо вам и за потраченное время. Я протестировал сейчас. Он отлично работает.