Reputation: 1001
I am trying to display 2 or 3 values from a record into a single cell row of a DataGridView. Below is a class representing a record to databind to:
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}
}
Id like to have a grid that looks like the following:
I am only interested in finding out how to create the second column titled Summary Information. I've been wondering if there is a way to have the information in the Summary Column displayed from a data bound source. For now I am displaying the information each in their own column but would like multiple values in single cell like the sample picture shows. If this can be done in a WinForms DataGridView (or maybe there is another control I should be using?) can someone please provide information or a link to information on how this can be done? Thanks in advance.
Upvotes: 2
Views: 3122
Reputation: 125197
You can use either of the following solutions:
CellFormatting
event to provide value for an unbound column.CellPainting
event to custom draw the content of a bound or unbound cell.DataRepeater
control.Option 1 - Adding Summary Property
You can add a new Summary
property containing the information which you want to show in cell:
Class Book
{
// rest of properties ...
public string Summary
{
get
{
return
$"Title: {this.Title}\n" +
$"Author: {this.Author}\n" +
$"Copyright Date: {this.CopyrightDate}";
}
}
}
Then you can simply use a bound column to show data in the DataGridView
.
Note 1: If the model is auto generated, you can put the new property in a partial class.
Note 2: In case of using DataTable
you can simply create a formula column by setting expression for the column.
Option 2 - Cell Formatting
You can add an unbound column and simply provide the value of the cell at runtime in CellFormatting
event of the DataGridView
control:
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}";
}
}
Option 3 - Using CellPaintig
event to custom draw cell
You can see an example of painting cell content with different fonts in this post: How can I create a footer for cell in DataGridView.
Option 4 - Using DataRepeater
Control
You can use a DataRepeater
control.
The Visual Basic Power Packs
DataRepeater
control is a scrollable. container for controls that display repeated data, for example, rows in a database table. It can be used as an alternative to theDataGridView
control when you need more control over the layout of the data. TheDataRepeater
"repeats" a group of related controls by creating multiple instances in a scrolling view. This enables users to view several records at the same time.
Upvotes: 4
Reputation: 1857
suppose you have dataGridView1
and you want to display data as you have shown in image of question. You can do something like below.
here we have used "\n" to add new lines in cell's value and DefaultCellStyle.WrapMode
will take care of putting data in new line properly.
you would need to set columns re-sizable as per content.
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;
Upvotes: 1