Browse Source

Re-apply a pre-attach tree selection once the tree loads

A model selection set before the SharpTreeView is attached to the visual tree
(e.g. AnalyzerTreeViewModel.Analyze selects its node, then the pane is shown)
was lost: the ListBox isn't an initialised ItemsControl yet, so the binder's
SelectedItems add silently dropped. Nothing re-applied it, so the analyzed row
showed unselected and keyboard gestures had no current node.

Making SharpTreeView focusable (for first-press Ctrl+A) unmasked this: with the
tree itself taking focus instead of delegating to the selected row's container,
keyboard handlers fell back to SelectedItem, which was empty. Re-sync on the
tree's Loaded event so the selection sticks once the control is ready.
pull/3755/head
Siegfried Pammer 1 month ago
parent
commit
b204e426e3
  1. 14
      ILSpy/Controls/TreeView/TreeSelectionBinder.cs

14
ILSpy/Controls/TreeView/TreeSelectionBinder.cs

@ -46,15 +46,27 @@ namespace ILSpy.Controls.TreeView
this.tree = tree ?? throw new ArgumentNullException(nameof(tree)); this.tree = tree ?? throw new ArgumentNullException(nameof(tree));
this.modelSelection = modelSelection ?? throw new ArgumentNullException(nameof(modelSelection)); this.modelSelection = modelSelection ?? throw new ArgumentNullException(nameof(modelSelection));
tree.SelectionChanged += OnTreeSelectionChanged; tree.SelectionChanged += OnTreeSelectionChanged;
tree.Loaded += OnTreeLoaded;
modelSelection.CollectionChanged += OnModelSelectionChanged; modelSelection.CollectionChanged += OnModelSelectionChanged;
// The model may already carry a selection (restored before the view was realised). // The model may already carry a selection (restored, or set by Analyze, before the view
// was realised). Apply it now; if the tree isn't attached yet the ListBox drops the
// SelectedItems add, so OnTreeLoaded re-applies once it is.
if (modelSelection.Count > 0) if (modelSelection.Count > 0)
SyncModelToTree(); SyncModelToTree();
} }
// A selection applied before the tree was attached doesn't stick (the ListBox isn't an
// initialised ItemsControl yet); re-apply once it loads so the row shows selected/focused.
void OnTreeLoaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (modelSelection.Count > 0 && tree.SelectedItems!.Count == 0)
SyncModelToTree();
}
public void Dispose() public void Dispose()
{ {
tree.SelectionChanged -= OnTreeSelectionChanged; tree.SelectionChanged -= OnTreeSelectionChanged;
tree.Loaded -= OnTreeLoaded;
modelSelection.CollectionChanged -= OnModelSelectionChanged; modelSelection.CollectionChanged -= OnModelSelectionChanged;
} }

Loading…
Cancel
Save