Scrollbar Annotations
- 5 minutes to read
Scrollbar annotations help users locate specific nodes—such as those with validation errors, focus, or selection. The TreeList
displays annotations as colored markers on the vertical scrollbar to visualize positions of corresponding nodes.
Enable Scrollbar Annotations
Use the OptionsScrollAnnotations property to enable specific annotations:
ShowErrors
- marks nodes with validation errors.ShowFocusedRow
- marks the focused node.ShowSelectedRows
- marks selected nodes.ShowCustomAnnotations
- marks nodes with custom annotations supplied via the CustomScrollAnnotation event.
// Enable annotations for the focused row.
treeList.OptionsScrollAnnotations.ShowFocusedRow = DefaultBoolean.True;
Note
The TreeList
control also displays scrollbar annotations for search requests if the Find Panel operates in search mode.
Custom Annotations
Handle the CustomScrollAnnotation event to supply custom annotation data. Use the TreeListScrollAnnotationInfo
class to specify annotation properties:
Node
- the associated TreeList node.Color
- the color of the annotation.
Add annotation objects to the e.Annotations
collection:
using DevExpress.XtraTreeList;
void treeList1_CustomScrollAnnotation(object sender, TreeListCustomScrollAnnotationsEventArgs e) {
TreeListNode node = treeList1.FindNodeByFieldValue("DEPARTMENT", "Finance");
e.Annotations = new List<TreeListScrollAnnotationInfo>();
TreeListScrollAnnotationInfo info = new TreeListScrollAnnotationInfo() {
Node = node,
Color = Color.Orange
};
e.Annotations.Add(info);
}
Use the e.SetAnnotations
method to apply annotations to a specific node. This method resets previous annotations.
using DevExpress.XtraTreeList;
void treeList1_CustomScrollAnnotation(object sender, TreeListCustomScrollAnnotationsEventArgs e) {
TreeListNode node = treeList1.FindNodeByFieldValue("DEPARTMENT", "Finance");
e.SetAnnotations(Color.Red, node);
}
Bookmarks with Scrollbar Annotations and Node Indicators
To implement user-defined bookmarks:
- Handle the TreeList.CustomScrollAnnotation event to associate nodes with annotations.
- Handle the TreeList.CustomDrawNodeIndicator event to draw bookmark glyphs.
- Handle the TreeList.ScrollAnnotationsStyle event to customize annotation appearance.
- Handle the
KeyDown
event to navigate between annotated nodes using TreeList.MoveToNextScrollAnnotation and TreeList.MoveToPrevScrollAnnotation methods.
using DevExpress.Utils;
using DevExpress.XtraEditors.Annotations;
using DevExpress.XtraTreeList.Menu;
using DevExpress.XtraTreeList.Nodes;
using DevExpress.XtraTreeList.Painter;
treeList1.CustomScrollAnnotation += OnCustomScrollAnnotation;
treeList1.CustomDrawNodeIndicator += OnCustomDrawRowIndicator;
treeList1.ScrollAnnotationsStyle += OnScrollAnnotationsStyle;
treeList1.KeyDown += OnKeyDown;
readonly HashSet<int> bookmarks = new HashSet<int>() { 5, 17, 74 };
// Set custom annotations.
void OnCustomScrollAnnotation(object sender, TreeListCustomScrollAnnotationsEventArgs e) {
TreeListNode[] rowHandles = bookmarks.Select(x => treeList1.FindNodeByID(x)).ToArray();
e.SetAnnotations(DevExpress.LookAndFeel.DXSkinColors.IconColors.Blue, rowHandles);
}
Utils.Design.ISvgPaletteProvider GetPalette() {
return Utils.Svg.SvgPaletteHelper.GetSvgPalette(treeList1.LookAndFeel, Utils.Drawing.ObjectState.Normal);
}
void OnScrollAnnotationsStyle(object sender, TreeListScrollAnnotationsStyleEventArgs e) {
var styleColor = ucScrollAnnotationsOptions.GetColor(e.Kind);
if(!styleColor.IsEmpty)
e.Color = styleColor;
}
// Draw a bookmark glyph.
void OnCustomDrawRowIndicator(object sender, CustomDrawNodeIndicatorEventArgs e) {
if(e.Node == null || treeList1.IsAutoFilterNode(e.Node))
return;
if(e.Info.ImageIndex == TreeListPainter.ErrorInNodeIndicatorImageIndex ||
e.Info.ImageIndex == TreeListPainter.ErrorInFocusedNodeIndicatorImageIndex) {
e.Info.ImageIndex = -1;
}
if(!ucScrollAnnotationsOptions.BookmarksEnabled || !bookmarks.Contains(e.Node.Id))
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(treeList1.FocusedNode);
if(e.KeyData == Keys.F2)
e.Handled = treeList1.MoveToNextScrollAnnotation(ScrollAnnotationKind.Custom);
if(e.KeyData == (Keys.F2 | Keys.Shift))
e.Handled = treeList1.MoveToPrevScrollAnnotation(ScrollAnnotationKind.Custom);
}
bool ToggleBookmark(TreeListNode node) {
int dataIndex = node != null ? node.Id : -1;
if(dataIndex < 0)
return false;
if(bookmarks.Contains(dataIndex))
bookmarks.Remove(dataIndex);
else
bookmarks.Add(dataIndex);
treeList1.RefreshScrollAnnotations(ScrollAnnotationKind.Custom);
treeList1.InvalidateNode(node);
return true;
}
Specific Notes
- The TreeListLookUpEdit does not support scrollbar annotations for Find Panel search results.
- Scrollbar annotations for selected nodes require multiple node selection mode.
- Fluent scrollbars remain visible when annotations are enabled. The
TreeList
control does not auto-hide them. See the following help topic for more information: WindowsFormsSettings.ScrollUIMode.