Skip to content

* MultiSelect Treeview#3839

Open
PWagner1 wants to merge 2 commits into
alphafrom
3837-feature-request-multiselect-treeview
Open

* MultiSelect Treeview#3839
PWagner1 wants to merge 2 commits into
alphafrom
3837-feature-request-multiselect-treeview

Conversation

@PWagner1

@PWagner1 PWagner1 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Multi-select TreeView (KryptonMultiSelectTreeView)

Closes #3837

Summary

Adds KryptonMultiSelectTreeView to Krypton.Toolkit.Utilities, a KryptonTreeView derivative with ListView-style extended selection for hierarchical data. The control exposes a SelectedNodes collection and supports Ctrl+click toggle, Shift+click range selection, rubber-band drag selection, and optional check-box selection that stays in sync with SelectedNodes.

A small, backward-compatible extension to core KryptonTreeView adds protected virtual IsNodeMultiSelected(TreeNode) so additional selected nodes paint with the existing StateMultiSelect palette styling.

Motivation

WinForms TreeView is single-select at the OS level. Issue #3837 requested a Krypton-styled control with:

  • Ctrl+click discrete selection
  • Shift+click range selection (visible flat order)
  • Click-drag rubber-band selection
  • Check-box selection
  • A SelectedNodes return type / collection API

KryptonTreeView already had partial checkbox-toggle multi-select via MultiSelect; this PR delivers the full feature set as a dedicated Utilities control scoped for V110.

Changes

New: KryptonMultiSelectTreeView (Krypton.Toolkit.Utilities)

Area Details
Control Components/KryptonMultiSelectTreeView/Controls Toolkit/KryptonMultiSelectTreeView.cs

Public API

  • SelectedNodesReadOnlyCollection<TreeNode>
  • SelectedNodesChanged — default event
  • EnableRubberBandSelection (default true)
  • SyncCheckBoxesToSelection (default true)
  • SetSelectedNodes(IEnumerable<TreeNode>)
  • ClearSelectedNodes()
  • SelectAllVisibleNodes()

Base KryptonTreeView.MultiSelect is hidden; this control manages its own selection model.

Core: KryptonTreeView

  • Added protected virtual bool IsNodeMultiSelected(TreeNode node) (default false)
  • Owner-draw path treats multi-selected nodes as selected for row highlight, images, and StateMultiSelect / StateCheckedMultiSelect palette overrides

No breaking changes to existing KryptonTreeView consumers.

TestForm

  • MultiSelectTreeViewExample — demo form with sample hierarchy, live selection label, Clear / Select All buttons
  • Start screen entry: Multi-Select TreeView

Changelog

  • V110 nightly entry under #3837

Behaviour notes

Interaction Behaviour
Plain click Selects a single node; updates SelectedNodes and check boxes (when enabled)

Rubber-band overlay is painted on the outer KryptonMultiSelectTreeView (not inner TreeView.Paint) because Krypton uses a custom WmPaint path on the hosted tree.

Implementation details

  • 64-bit TVM_GETITEMRECT: HTREEITEM is passed via Marshal.WriteIntPtr into the first pointer-sized field of RECT (matches WinForms TreeNode.Bounds), with fallback to TopNode / NextVisibleNode layout
  • Rubber-band vs modifiers: Mouse-down defers plain clicks when rubber-banding is enabled so drag does not fight single-select; Ctrl/Shift clicks are handled immediately in BeforeSelect
  • Check-box sync: All nodes in the tree are updated inside BeginUpdate/EndUpdate; sync runs after focus changes and on selection no-op paths so Shift+click range keeps check states aligned

Test plan

Manual validation via TestForm → Multi-Select TreeView:

  • Plain click selects one node; label shows SelectedNodes; check box checks
  • Ctrl+click toggles multiple non-contiguous nodes on/off (highlight + check boxes)
  • Click node A, Shift+click node C — range A–C selected and checked; nodes outside range unchecked
  • Drag rubber band across several rows — band visible, nodes on release selected (Ctrl+drag extends)
  • Select All / Clear Selection buttons
  • Theme switch — multi-select highlights use Krypton palette (StateMultiSelect)
  • Build: Krypton.Toolkit.Utilities and TestForm on net48 and net11.0-windows

Packaging

Ships in the Krypton.Toolkit.Utilities assembly (same NuGet surface as other Utilities controls, e.g. KryptonCircularProgressBar, KryptonTreeComboBox).

# Multi-select TreeView (`KryptonMultiSelectTreeView`)

Closes [#3837](#3837)

## Summary

Adds `KryptonMultiSelectTreeView` to `Krypton.Toolkit.Utilities`, a `KryptonTreeView` derivative with ListView-style extended selection for hierarchical data. The control exposes a `SelectedNodes` collection and supports Ctrl+click toggle, Shift+click range selection, rubber-band drag selection, and optional check-box selection that stays in sync with `SelectedNodes`.

A small, backward-compatible extension to core `KryptonTreeView` adds `protected virtual IsNodeMultiSelected(TreeNode)` so additional selected nodes paint with the existing `StateMultiSelect` palette styling.

## Motivation

WinForms `TreeView` is single-select at the OS level. Issue #3837 requested a Krypton-styled control with:

- Ctrl+click discrete selection
- Shift+click range selection (visible flat order)
- Click-drag rubber-band selection
- Check-box selection
- A `SelectedNodes` return type / collection API

`KryptonTreeView` already had partial checkbox-toggle multi-select via `MultiSelect`; this PR delivers the full feature set as a dedicated Utilities control scoped for V110.

## Changes

### New: `KryptonMultiSelectTreeView` (`Krypton.Toolkit.Utilities`)

| Area | Details |
|------|---------|
| Control | `Components/KryptonMultiSelectTreeView/Controls Toolkit/KryptonMultiSelectTreeView.cs` |
| Helpers | `Components/KryptonMultiSelectTreeView/General/TreeViewMultiSelectHelper.cs` — visible/all node enumeration, `TVM_GETITEMRECT` bounds (64-bit safe), rubber-band rectangle normalization |
| Designer | `Components/KryptonMultiSelectTreeView/Designers/Designers/KryptonMultiSelectTreeViewDesigner.cs` |

**Public API**

- `SelectedNodes` — `ReadOnlyCollection<TreeNode>`
- `SelectedNodesChanged` — default event
- `EnableRubberBandSelection` (default `true`)
- `SyncCheckBoxesToSelection` (default `true`)
- `SetSelectedNodes(IEnumerable<TreeNode>)`
- `ClearSelectedNodes()`
- `SelectAllVisibleNodes()`

Base `KryptonTreeView.MultiSelect` is hidden; this control manages its own selection model.

### Core: `KryptonTreeView`

- Added `protected virtual bool IsNodeMultiSelected(TreeNode node)` (default `false`)
- Owner-draw path treats multi-selected nodes as selected for row highlight, images, and `StateMultiSelect` / `StateCheckedMultiSelect` palette overrides

No breaking changes to existing `KryptonTreeView` consumers.

### TestForm

- `MultiSelectTreeViewExample` — demo form with sample hierarchy, live selection label, Clear / Select All buttons
- Start screen entry: **Multi-Select TreeView**

### Changelog

- V110 nightly entry under [#3837](#3837)

## Behaviour notes

| Interaction | Behaviour |
|-------------|-----------|
| Plain click | Selects a single node; updates `SelectedNodes` and check boxes (when enabled) |
| Ctrl+click | Toggles node in/out of `SelectedNodes` |
| Shift+click | Selects visible range from anchor (`_selectionAnchor` or `SelectedNode`) to clicked node; checks/unchecks to match |
| Rubber-band drag | Drag on empty or node area (plain click only; Ctrl/Shift bypass deferral); intersecting visible nodes are selected; Ctrl extends existing selection |
| Check boxes | When `CheckBoxes = true` and `SyncCheckBoxesToSelection = true`, checking/unchecking updates `SelectedNodes` and vice versa |

Rubber-band overlay is painted on the outer `KryptonMultiSelectTreeView` (not inner `TreeView.Paint`) because Krypton uses a custom `WmPaint` path on the hosted tree.

## Implementation details

- **64-bit `TVM_GETITEMRECT`**: HTREEITEM is passed via `Marshal.WriteIntPtr` into the first pointer-sized field of `RECT` (matches WinForms `TreeNode.Bounds`), with fallback to `TopNode` / `NextVisibleNode` layout
- **Rubber-band vs modifiers**: Mouse-down defers plain clicks when rubber-banding is enabled so drag does not fight single-select; Ctrl/Shift clicks are handled immediately in `BeforeSelect`
- **Check-box sync**: All nodes in the tree are updated inside `BeginUpdate`/`EndUpdate`; sync runs after focus changes and on selection no-op paths so Shift+click range keeps check states aligned

## Test plan

Manual validation via TestForm → **Multi-Select TreeView**:

- [ ] Plain click selects one node; label shows `SelectedNodes`; check box checks
- [ ] Ctrl+click toggles multiple non-contiguous nodes on/off (highlight + check boxes)
- [ ] Click node A, Shift+click node C — range A–C selected and checked; nodes outside range unchecked
- [ ] Drag rubber band across several rows — band visible, nodes on release selected (Ctrl+drag extends)
- [ ] **Select All** / **Clear Selection** buttons
- [ ] Theme switch — multi-select highlights use Krypton palette (`StateMultiSelect`)
- [ ] Build: `Krypton.Toolkit.Utilities` and `TestForm` on `net48` and `net11.0-windows`

## Packaging

Ships in the **`Krypton.Toolkit.Utilities`** assembly (same NuGet surface as other Utilities controls, e.g. `KryptonCircularProgressBar`, `KryptonTreeComboBox`).
@PWagner1 PWagner1 added this to the Version 110 milestone Jul 3, 2026
@PWagner1 PWagner1 requested a review from a team as a code owner July 3, 2026 14:17
@PWagner1 PWagner1 added version:110 All things to do with V110. area:toolkit-utilities All issues relating to `Krypton.Utilities`. labels Jul 3, 2026
@PWagner1 PWagner1 linked an issue Jul 3, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:toolkit-utilities All issues relating to `Krypton.Utilities`. version:110 All things to do with V110.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: MultiSelect Treeview

1 participant