Cells
- 10 minutes to read
Content Alignment
Data Grid cells that display numeric values align their content to the right. Cells that display data of other types arrange their content to the left. To change cell content alignment, handle the ColumnView.RowCellDefaultAlignment event.
Selection Modes
With default Grid settings, users can select only entire rows. Set the GridOptionsSelection.MultiSelectMode property to the GridMultiSelectMode.CellSelect value to allow users select individual cells. In this mode, users can utilize “Ctrl” and “Shift” keys to select multiple cells at once.
Related API
GridView.SelectCell, GridView.SelectCells — Methods that allow you to select individual cells and/or cell ranges.
GridView.GetSelectedCells — Return selected cells or parent Grid columns of these cells.
Display Text and Cell Value
A cell value is the value stored in a data source. A cell’s display text is the value shown to users. When the Data Grid sorts or filters data, it processes the cell values (and not display texts). You can make the control sort and filter data by cell display values instead. To do so, utilize the GridColumn.SortMode and GridColumn.FilterMode properties.
Certain Grid features (for example, formatting) alter the way actual cell values are shown to end users. To manually modify a cell’s display text without changing the underlying value, handle the ColumnView.CustomColumnDisplayText event. In the following example, cells that belong to the “Length” column show nothing if their values are greater than 20.
gridView.CustomColumnDisplayText += (sender, e) => {
if(e.Column.FieldName == "Length") {
double val = (double)e.Value;
if (val > 20)
e.DisplayText = string.Empty;
}
};
How to Place an Image in a Grid Cell
Depending on your task, you can use different techniques to display images (glyphs, icons, pictures) inside Data Grid cells. Please note that you cannot use the GridColumn.CellAppearance.Image
property (the Data Grid ignores this setting).
Editor Context Images
The RepositoryItemTextEdit.ContextImageOptions group allows you to assign a raster or vector icon to a RepositoryItemTextEdit object. Use this technique if you need to display the same icon for all column cells, and keep the cell text editable.
RepositoryItemTextEdit textEdit = new RepositoryItemTextEdit();
textEdit.ContextImageOptions.Image = Image.FromFile("..\\..\\img.bmp");
gridView1.Columns["ContextImage"].ColumnEdit = textEdit;
gridControl1.RepositoryItems.Add(textEdit);
To display a different icon for individual cells, create a separate RepositoryItemTextEdit and handle the GridView.CustomRowCellEdit event to assign this repository item to required cells. In the example below, cells display the “repositoryItemTextEdit2” editor if these rows store orders to Denmark.
private void GridView1_CustomRowCellEdit1(object sender, CustomRowCellEditEventArgs e) {
if (e.RowHandle != GridControl.NewItemRowHandle && e.Column.FieldName == "ShipCountry"
&& e.CellValue.ToString() == "Denmark") {
e.RepositoryItem = repositoryItemTextEdit2;
}
}
Check Edit with Images
If you need to replace Boolean cell values with icons, assign a Check Edit editor to this column. The editor’s ImageOptions property allows you to set icons for the “Checked” and “Unchecked” editor states. You also need to set the editor’s CheckBoxOptions.Style property to “custom”.
using DevExpress.XtraEditors.Repository;
RepositoryItemCheckEdit checkEdit =
gridControl1.RepositoryItems.Add("CheckEdit") as RepositoryItemCheckEdit;
checkEdit.ImageOptions.ImageChecked = Image.FromFile("..\\..\\read.bmp");
checkEdit.ImageOptions.ImageUnchecked = Image.FromFile("..\\..\\unread.bmp");
checkEdit.CheckBoxOptions.Style = DevExpress.XtraEditors.Controls.CheckBoxStyle.Custom;
gridView1.Columns["IsRead"].ColumnEdit = checkEdit;
gridControl1.RepositoryItems.Add(checkEdit);
Image Combo Box
If your cells display enumeration values that you wish to replace with images, use the ImageComboBoxEdit editor linked to an ImageList or a DevExpress image collection.
RepositoryItemImageComboBox imageCombo =
gridControl1.RepositoryItems.Add("ImageComboBoxEdit") as RepositoryItemImageComboBox;
DevExpress.Utils.ImageCollection images = new DevExpress.Utils.ImageCollection();
images.AddImage(Image.FromFile("..\\..\\Minor.png"));
images.AddImage(Image.FromFile("..\\..\\Moderate.png"));
images.AddImage(Image.FromFile("..\\..\\Severe.png"));
imageCombo.SmallImages = images;
// The first argument is the item description, visible to end users
// The second argument is the cell (data source) value
// The third argument is the index of an image inside the "SmallImages" collection
imageCombo.Items.Add(new ImageComboBoxItem("Minor", (short)1, 0));
imageCombo.Items.Add(new ImageComboBoxItem("Moderate", (short)2, 1));
imageCombo.Items.Add(new ImageComboBoxItem("Severe", (short)3, 2));
imageCombo.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
gridView1.Columns["Severity"].ColumnEdit = imageCombo;
gridControl1.RepositoryItems.Add(imageCombo);
Conditional Formatting
This technique is recommended when you have a static icon set to visualize different values or value ranges. In this scenario, icons are displayed next to cell values.
Documentation: Appearance and Conditional Formatting | Demo: Excel Style Filtering
Fill Cells with Images
Use the PictureEdit editor to fill an entire Grid cell with an image.
RepositoryItemPictureEdit pictureEdit =
gridControl1.RepositoryItems.Add("PictureEdit") as RepositoryItemPictureEdit;
pictureEdit.SizeMode = PictureSizeMode.Zoom;
pictureEdit.NullText = " ";
gridView1.Columns["Picture"].ColumnEdit = pictureEdit;
gridControl1.RepositoryItems.Add(pictureEdit);
Custom Draw
The GridView.CustomDrawCell event allows you to paint images inside Grid cells.
private void GridView1_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e) {
if (e.RowHandle != GridControl.NewItemRowHandle && e.Column.FieldName == "ShipCountry"
&& e.CellValue.ToString() == "Denmark") {
e.DefaultDraw();
//TODO: specify required offsets
e.Cache.DrawImage(img, e.Bounds.X + offsetX, e.Bounds.Y + offsetY);
}
}
HTML Formatting
Use the Image tag to embed images into cells. Note that this technique makes a cell non-editable.
gridView1.HtmlImages = imageCollection1;
gridView1.RowHeight = 60;
// Create an unbound column
GridColumn unbound = new GridColumn();
unbound.UnboundDataType = typeof(string);
unbound.FieldName = "unboundImageColumn";
unbound.Visible = true;
unbound.Caption = "Icon";
gridView1.Columns.Add(unbound);
// Assign a RepositoryItemHypertextLabel as the unbound column editor
RepositoryItemHypertextLabel htLabel = new RepositoryItemHypertextLabel();
htLabel.HtmlImages = imageCollection1;
gridControl1.RepositoryItems.Add(htLabel);
unbound.ColumnEdit = htLabel;
// Set custom cell text
gridView1.CustomUnboundColumnData += GridView1_CustomUnboundColumnData;
private void GridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
{
if (e.Column.Caption == "Icon")
{
// Image from HtmlImages collection
e.Value = "<image=add_32x32.png>";
// Image from resources
//e.Value = "<image=#_589812_200>";
}
}
Unbound Columns
If you need a column with images, not associated with specific data source values, create an unbound column with a RepositoryItemPictureEdit object as an in-place editor. Handle the ColumnView.CustomUnboundColumnData event to supply this column with images.
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Card;
Dictionary<string, Image> imageCache = new Dictionary<string, Image>();
private void CardView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) {
if (e.IsSetData)
return;
CardView view = sender as CardView;
var path = (string)view.GetListSourceRowCellValue(e.ListSourceRowIndex, "Path");
if (string.IsNullOrEmpty(path))
return;
try {
e.Value = LoadImage(path);
}
catch { }
}
Image LoadImage(string path) {
Image img;
if(!imageCache.TryGetValue(path, out img)) {
if(File.Exists(path))
img = Image.FromFile(path);
imageCache.Add(path, img);
}
return img;
}
Cell Merging
In GridView and BandedGridView Views, cells with the same values can automatically merge. Note that merging relies on cell values, not cell display text.
Merged cells impose the following limitations:
- End users cannot edit merged cells.
- Row multi-selection is disabled.
- Merged rows cannot display the preview sections. If the GridOptionsView.ShowPreview option is set to true, the neighboring cells with identical values cannot be merged, regardless of the GridOptionsView.AllowCellMerge property’s value.
- Appearance settings for focused rows and cells are ignored (the GridViewAppearances.FocusedRow and GridViewAppearances.FocusedCell properties).
- Appearance settings used to paint even and odd rows are ignored (the GridViewAppearances.EvenRow and GridViewAppearances.OddRow properties).
Related API
GridOptionsView.AllowCellMerge — Enables automatic cell merge for the entire View.
OptionsColumn.AllowMerge — Enables automatic cell merge for this column only. This property has priority over the global GridOptionsView.AllowCellMerge setting.
GridView.CellMerge — This event allows you to implement your custom algorithm and manually merge cells.
In this example, the Data Grid contains the “Created By” column that displays e-mail addresses. The ColumnView.CustomColumnDisplayText event is handled to trim these addresses to domain names. Since this event changes only cell display text, cell values remain intact and no merging occurs. To fix that, the GridView.CellMerge event is handled.
// Trim e-mail addresses
private void gridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e) {
if (e.Column == colCreatorID) {
string email = e.DisplayText;
string domain = email.Substring(email.IndexOf('@') + 1);
e.DisplayText = domain;
}
}
// Custom cell merge
private void gridView1_CellMerge(object sender, DevExpress.XtraGrid.Views.Grid.CellMergeEventArgs e) {
GridView view = sender as GridView;
if(view == null) return;
if (e.Column == colCreatorID) {
string text1 = view.GetRowCellDisplayText(e.RowHandle1, colCreatorID);
string text2 = view.GetRowCellDisplayText(e.RowHandle2, colCreatorID);
e.Merge = (text1 == text2);
e.Handled = true;
}
}
Access Grid Cells in Code
ColumnView.GetRowCellDisplayText and ColumnView.GetRowCellValue
Return cell value and display text for any grid cell.
ColumnView.GetFocusedRowCellDisplayText and ColumnView.GetFocusedRowCellValue
Return cell value and display text for any cell that belongs to the currently focused row.
ColumnView.FocusedRowHandle and ColumnView.FocusedColumn
Set the focused row and column to select a required cell.
ColumnView.CellValueChanging and ColumnView.CellValueChanged
These events fire in response to end-user modifications to cell values.