Есть ли способ иметь WinForms DataGridView со столбцом, отображающим несколько значений из записи

Я пытаюсь отобразить 2 или 3 значения из записи в одну строку ячейки DataGridView. Ниже приведен класс, представляющий запись для привязки данных:

Class Book
{
  public int BookId {get;set;}
  public string Title {get;set;}
  public string Publisher {get;set}
  public string Author {get;set}
  public Date CopyrightDate {get;set}
  public byte[] BookCoverImage {get;set}
}

Я хотел бы иметь сетку, которая выглядит следующим образом:

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

Меня интересует только то, как создать второй столбец под названием «Сводная информация». Мне было интересно, есть ли способ отображать информацию в сводной колонке из источника с привязкой к данным. На данный момент я отображаю информацию каждый в своем столбце, но хотел бы иметь несколько значений в одной ячейке, как показано на примере изображения. Если это можно сделать в WinForms DataGridView (или, может быть, есть другой элемент управления, который я должен использовать?), Может ли кто-нибудь предоставить информацию или ссылку на информацию о том, как это можно сделать? Заранее спасибо.


person Robertcode    schedule 05.06.2018    source источник
comment
Как объединить ячейку DataGridView в Winforms и C# DataGridView Colspan может вам помочь.   -  person mmushtaq    schedule 05.06.2018
comment
Роберт, я добавил ответ, который должен решить вашу проблему. Дайте мне знать, если вы хотите сделать что-то еще!   -  person Amit    schedule 05.06.2018
comment
Вы также можете посмотреть это опубликовать   -  person TaW    schedule 05.06.2018


Ответы (2)


предположим, что у вас есть dataGridView1, и вы хотите отображать данные, как показано на изображении вопроса. Вы можете сделать что-то вроде ниже.

здесь мы использовали "\n" для добавления новых строк в значение ячейки, а DefaultCellStyle.WrapMode позаботится о правильном размещении данных в новой строке.

вам нужно будет установить столбцы, изменяемые по размеру в соответствии с содержимым.

List<Book> bookList = new List<Book>();
for(int i = 0; i < 3; i++)
{
    //for simplicity of solution, i have used cover as string not image,
    // you can perform same logic with cover as image too.
    bookList.Add(new Book(i, "title" + i, "publisher" + i, "auther" + i, "cover" + i));
}

DataTable dt = new DataTable();
dt.Columns.Add("ColBook");
dt.Columns.Add("ColData");

foreach(Book book in bookList)
{
    DataRow dr = dt.NewRow();
    dr["ColBook"] = book.BookCoverImage;
    dr["ColData"] = "Title:"+book.Title + "\nPublisher:" + book.Publisher + "\nAuthor:" + book.Author;
    dt.Rows.Add(dr);
}

dataGridView1.DataSource = dt;
dataGridView1.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
person Amit    schedule 05.06.2018
comment
Этот вариант может работать на данный момент. Когда данные будут возвращены из репозитория, я попрошу сервисный уровень преобразовать записи во время создания шага BindingList‹Book›, чтобы переводы строк были преобразованы в новое свойство класса (SummaryInfo). Это будет DTO, поэтому теперь список BindingList‹BookDto› загружается в BindingSource.DataSource, который я назначаю свойству DataSource сетки. Я надеялся, что есть способ как-то направить пользовательский элемент управления в ячейку или что-то встроенное для этого. Я заметил, что у Telerik есть ListControl, который, похоже, тоже делает что-то подобное. - person Robertcode; 05.06.2018
comment
@Robertcode также предпочтительным для вас способом, если ваш DTO может выставить свойство, созданное как комбинированное (что-то вроде ...Title + "\nPublisher:" + ...), оно будет автоматически преобразовано в DataSource представления сетки, верно? Тогда это должно сработать. попробуй - person Amit; 05.06.2018
comment
использование перевода строки работает вместе с параметрами DataGridView, указанными выше. Этого пока хватит. Спасибо. - person Robertcode; 05.06.2018

Вы можете использовать любое из следующих решений:

  • Добавьте в класс сводное свойство только для чтения и используйте связанный столбец.
  • Используйте событие CellFormatting, чтобы указать значение для несвязанного столбца.
  • Используйте событие CellPainting для пользовательского рисования содержимого связанной или несвязанной ячейки.
  • Используйте DataRepeater.

Вариант 1. Добавление сводного свойства

Вы можете добавить новое свойство Summary, содержащее информацию, которую вы хотите отобразить в ячейке:

Class Book
{
    // rest of properties ...
    public string Summary
    {
        get 
        {
            return
                $"Title: {this.Title}\n" +
                $"Author: {this.Author}\n" +
                $"Copyright Date: {this.CopyrightDate}";
        }
    }
}

Затем вы можете просто использовать связанный столбец для отображения данных в таблице DataGridView.

Примечание 1. Если модель создается автоматически, вы можете поместить новое свойство в разделяемый класс.

Примечание 2. В случае использования DataTable вы можете просто создать столбец формулы, установив выражение для столбца.

Вариант 2. Форматирование ячеек

Вы можете добавить несвязанный столбец и просто указать значение ячейки во время выполнения в событии CellFormatting элемента управления DataGridView:

private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    var dgv = (DataGridView)sender;
    if (e.RowIndex < 0 || e.RowIndex == dgv.NewRowIndex)
        return;
    if (e.ColumnIndex == 1 /*The column index which you want to format*/)
    {
        var book = dgv.Rows[e.RowIndex].DataBoundItem as Book;
        if (book != null)
            e.Value =
                $"Title: {book.Title}\n" +
                $"Author: {book.Author}\n" +
                $"Copyright Date: {book.CopyrightDate}";
    }
}

Вариант 3. Использование события CellPaintig для пользовательской ячейки рисования

Вы можете увидеть пример рисования содержимого ячейки разными шрифтами в этом сообщении: Как создать нижний колонтитул для ячейки в DataGridView .

Вариант 4 — Использование элемента управления DataRepeater

Вы можете использовать элемент управления DataRepeater.

Элемент управления Visual Basic Power Packs DataRepeater прокручиваемый. контейнер для элементов управления, которые отображают повторяющиеся данные, например, строки в таблице базы данных. Его можно использовать в качестве альтернативы элементу управления DataGridView, когда вам нужен больший контроль над расположением данных. DataRepeater «повторяет» группу связанных элементов управления, создавая несколько экземпляров в представлении с прокруткой. Это позволяет пользователям просматривать несколько записей одновременно.

person Reza Aghaei    schedule 05.06.2018