Scrollbar Annotations
- 5 minutes to read
When grids contain many rows, locating those with validation errors, and those that are focused or selected, can be difficult. To help locate these rows expeditiously, display scrollbar annotations. The latter are colored marks on the vertical scrollbar that reflect the location of corresponding rows in the grid.
How to Enable
The GridView.OptionsScrollAnnotations property provides access to options that allow you to enable/disable specific annotations.
- ShowErrors — specifies whether to mark rows with validation errors
- ShowFocusedRow — specifies whether to mark the focused row
- ShowSelectedRows — specifies whether to mark selected rows
- ShowCustomAnnotations — specifies whether to mark rows with custom annotations provided using a dedicated event (see below)
Scrollbar annotations are disabled if the corresponding property is set to Default. You should explicitly set the options to True to enable the required scrollbar annotations.
// Enable annotations for the focused row.
gridView.OptionsScrollAnnotations.ShowFocusedRow = DefaultBoolean.True;
Scrollbar annotations have the following limitations:
- lookup editors (see GridLookUpEdit, SearchLookUpEdit) do not support scrollbar annotations for search requests in the Find Panel;
- scrollbar annotations for validation errors and search requests are not supported in the Server Mode;
- scrollbar annotations for selected rows are only supported in the multiple row selection mode (see ColumnViewOptionsSelection.MultiSelect).
Custom Annotations
The GridView.CustomScrollAnnotation event allows you to provide data about the required custom annotations. Data is represented by the GridScrollAnnotationInfo type, which exposes the following properties.
- RowHandle — handle of the required row (see Row handles in the Rows topic)
- Color — color of the mark on the scrollbar
When handling this event, create data objects and add them to the Annotations collection in the event arguments.
void OnCustomScrollAnnotation(object sender, GridCustomScrollAnnotationsEventArgs e) {
GridScrollAnnotationInfo info = new GridScrollAnnotationInfo() { RowHandle = 74, Color = Color.Red };
e.Annotations.Add(info);
}
The SetAnnotations method allows you to set annotations for a row array. Note that this method does not add annotations, but resets them.
void OnCustomScrollAnnotation(object sender, GridCustomScrollAnnotationsEventArgs e) {
int[] rowHandles = new int[] { 5, 17, 74 };
e.SetAnnotations(Color.Red, rowHandles);
}
How to: Create Row Bookmarks Using Scrollbar Annotations and Row Indicators
Note
Demo Run the Scrollbar Annotations & Bookmarks module in the XtraGrid demo to see the functionality in action.
You can provide users with the ability to bookmark specific rows and navigate between them using the keyboard. To implement this functionality, handle the following events:
- the GridView.CustomScrollAnnotation event — to associate specific rows with custom annotations;
- the GridView.CustomDrawRowIndicator event — to draw a bookmark glyph against each annotated row;
- the KeyDown event — to implement forward and back navigation between annotated rows. To scroll the grid in code, use the GridView.MoveToNextScrollAnnotation and GridView.MoveToPrevScrollAnnotation methods.
using DevExpress.XtraEditors.Annotations;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.Drawing;
gridView.CustomScrollAnnotation += OnCustomScrollAnnotation;
gridView.CustomDrawRowIndicator += OnCustomDrawRowIndicator;
gridView.KeyDown += OnKeyDown;
readonly HashSet<int> bookmarks = new HashSet<int>() { 5, 17, 74 };
// Set custom annotations.
void OnCustomScrollAnnotation(object sender, GridCustomScrollAnnotationsEventArgs e) {
int[] rowHandles = bookmarks.Select(x => gridView.GetRowHandle(x)).ToArray();
e.SetAnnotations(DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue, rowHandles);
}
Utils.Design.ISvgPaletteProvider GetPalette() {
return Utils.Svg.SvgPaletteHelper.GetSvgPalette(gridControl.LookAndFeel, Utils.Drawing.ObjectState.Normal);
}
// Draw a bookmark glyph.
void OnCustomDrawRowIndicator(object sender, RowIndicatorCustomDrawEventArgs e) {
if(e.RowHandle >= 0) {
if(e.Info.ImageIndex == GridPainter.IndicatorError ||
e.Info.ImageIndex == GridPainter.IndicatorFocusedError) {
// suppress error indicator
e.Info.ImageIndex = (e.RowHandle == gridView.FocusedRowHandle) ? GridPainter.IndicatorFocused : -1;
}
if(!bookmarks.Contains(gridView.GetDataSourceRowIndex(e.RowHandle)))
return;
e.DefaultDraw();
var bookmarkImage = svgImageCollection.GetImage("bookmark", GetPalette(), ScaleDPI.ScaleSize(new Size(8, 8)));
var imageBounds = PlacementHelper.Arrange(bookmarkImage.Size, e.Bounds, ContentAlignment.MiddleLeft);
e.Cache.DrawImageUnscaled(bookmarkImage, imageBounds);
e.Handled = true;
}
}
// Implement forward and back navigation.
void OnKeyDown(object sender, KeyEventArgs e) {
if(e.KeyData == (Keys.F2 | Keys.Control) || e.KeyData == (Keys.B | Keys.Control))
e.Handled = ToggleBookmark(gridView.FocusedRowHandle);
if(e.KeyData == Keys.F2)
e.Handled = gridView.MoveToNextScrollAnnotation(ScrollAnnotationKind.Custom);
if(e.KeyData == (Keys.F2 | Keys.Shift))
e.Handled = gridView.MoveToPrevScrollAnnotation(ScrollAnnotationKind.Custom);
}
bool ToggleBookmark(int handle) {
int dataIndex = gridView.GetDataSourceRowIndex(handle);
if(dataIndex < 0)
return false;
if(bookmarks.Contains(dataIndex))
bookmarks.Remove(dataIndex);
else
bookmarks.Add(dataIndex);
gridView.RefreshScrollAnnotations(ScrollAnnotationKind.Custom);
gridView.InvalidateRow(handle);
return true;
}