windowsforms-120556-controls-and-libraries-data-grid-scrolling-scrollbar-annotations.md
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.
The GridView.OptionsScrollAnnotations property provides access to options that allow you to enable/disable specific annotations.
Scrollbar annotations are disabled if a property equals to Default. Set the property to True to enable them.
// Enable annotations for the focused row.
gridView.OptionsScrollAnnotations.ShowFocusedRow = DefaultBoolean.True;
' Enable annotations for the focused row.
gridView.OptionsScrollAnnotations.ShowFocusedRow = DefaultBoolean.True
The grid control also displays scrollbar annotations for search requests if the Find Panel is in search mode.
Scrollbar annotations have the following limitations.
GridControl does not auto-hide them. See the following help topic for more information: WindowsFormsSettings.ScrollUIMode.The GridView.CustomScrollAnnotation event allows you to specify custom annotations. The GridScrollAnnotationInfo type specifies data about custom annotations and exposes the following properties:
When handling this event, explicitly initialize the e.Annotations collection, create data objects, and add them to the collection.
using using DevExpress.XtraGrid.Views.Grid;
void OnCustomScrollAnnotation(object sender, GridCustomScrollAnnotationsEventArgs e) {
e.Annotations = new List<GridScrollAnnotationInfo>();
GridScrollAnnotationInfo info = new GridScrollAnnotationInfo() { RowHandle = 74, Color = Color.Red };
e.Annotations.Add(info);
}
Imports using DevExpress.XtraGrid.Views.Grid
Private Sub OnCustomScrollAnnotation(ByVal sender As Object, ByVal e As GridCustomScrollAnnotationsEventArgs)
e.Annotations = New List(Of GridScrollAnnotationInfo)()
Dim info As New GridScrollAnnotationInfo() With {.RowHandle = 74, .Color = Color.Red}
e.Annotations.Add(info)
End Sub
You can also use the e.SetAnnotations method to set annotations for a row array.
void OnCustomScrollAnnotation(object sender, GridCustomScrollAnnotationsEventArgs e) {
int[] rowHandles = new int[] { 5, 17, 74 };
e.SetAnnotations(Color.Red, rowHandles);
}
Private Sub OnCustomScrollAnnotation(ByVal sender As Object, ByVal e As GridCustomScrollAnnotationsEventArgs) Handles gridView.CustomScrollAnnotation
Dim rowHandles() As Integer = {5, 17, 74}
e.SetAnnotations(Color.Red, rowHandles)
End Sub
Use the RefreshScrollAnnotations method to force the grid control to update/redraw scrollbar annotations.
Note
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 GridView.ScrollAnnotationsStyle event — to customize the scrollbar annotation color and alignment.
The Control.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.ScrollAnnotationsStyle += OnScrollAnnotationsStyle;
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);
}
readonly AnnotationsStyle style = new AnnotationsStyle();
void OnScrollAnnotationsStyle(object sender, GridScrollAnnotationsStyleEventArgs e) {
var styleColor = style.GetColor(e.Kind);
if(!styleColor.IsEmpty)
e.Color = styleColor;
}
// 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) {
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;
}
}
Utils.Design.ISvgPaletteProvider GetPalette() {
return Utils.Svg.SvgPaletteHelper.GetSvgPalette(gridControl.LookAndFeel, Utils.Drawing.ObjectState.Normal);
}
// 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;
}
Imports DevExpress.XtraEditors.Annotations
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.Drawing
Private ReadOnly bookmarks As New HashSet(Of Integer)() From {5, 17, 74}
' Set custom annotations.
Private Sub OnCustomScrollAnnotation(ByVal sender As Object, ByVal e As GridCustomScrollAnnotationsEventArgs) Handles gridView.CustomScrollAnnotation
Dim rowHandles() As Integer = bookmarks.Select(Function(x) gridView.GetRowHandle(x)).ToArray()
e.SetAnnotations(DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue, rowHandles)
End Sub
Private ReadOnly style As New AnnotationsStyle()
Private Sub OnScrollAnnotationsStyle(ByVal sender As Object, ByVal e As GridScrollAnnotationsStyleEventArgs) Handles gridView.ScrollAnnotationsStyle
Dim styleColor = style.GetColor(e.Kind)
If Not styleColor.IsEmpty Then
e.Color = styleColor
End If
End Sub
' Draw a bookmark glyph.
Private Sub OnCustomDrawRowIndicator(ByVal sender As Object, ByVal e As RowIndicatorCustomDrawEventArgs) Handles gridView.CustomDrawRowIndicator
If e.RowHandle >= 0 Then
If e.Info.ImageIndex = GridPainter.IndicatorError OrElse e.Info.ImageIndex = GridPainter.IndicatorFocusedError Then
e.Info.ImageIndex = If((e.RowHandle = gridView.FocusedRowHandle), GridPainter.IndicatorFocused, -1)
End If
If (Not bookmarks.Contains(gridView.GetDataSourceRowIndex(e.RowHandle))) Then
Return
End If
e.DefaultDraw()
Dim bookmarkImage = svgImageCollection.GetImage("bookmark", GetPalette(), ScaleDPI.ScaleSize(New Size(8, 8)))
Dim imageBounds = PlacementHelper.Arrange(bookmarkImage.Size, e.Bounds, ContentAlignment.MiddleLeft)
e.Cache.DrawImageUnscaled(bookmarkImage, imageBounds)
e.Handled = True
End If
End Sub
Private Function GetPalette() As Utils.Design.ISvgPaletteProvider
Return Utils.Svg.SvgPaletteHelper.GetSvgPalette(gridControl.LookAndFeel, Utils.Drawing.ObjectState.Normal)
End Function
' Implement forward and back navigation.
Private Sub OnGridKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles gridView.KeyDown
If e.KeyData = Keys.F2 Then
e.Handled = gridView.MoveToNextScrollAnnotation(ScrollAnnotationKind.Custom)
End If
If e.KeyData = (Keys.F2 Or Keys.Shift) Then
e.Handled = gridView.MoveToPrevScrollAnnotation(ScrollAnnotationKind.Custom)
End If
If e.KeyData = (Keys.F2 Or Keys.Control) OrElse e.KeyData = (Keys.B Or Keys.Control) Then
e.Handled = ToggleBookmark(gridView.FocusedRowHandle)
End If
End Sub
Private Function ToggleBookmark(ByVal handle As Integer) As Boolean
Dim dataIndex As Integer = gridView.GetDataSourceRowIndex(handle)
If dataIndex < 0 Then
Return False
End If
If bookmarks.Contains(dataIndex) Then
bookmarks.Remove(dataIndex)
Else
bookmarks.Add(dataIndex)
End If
gridView.RefreshScrollAnnotations(ScrollAnnotationKind.Custom)
gridView.InvalidateRow(handle)
Return True
End Function
See Also