Fixed feature to preserve the state (expansions and selection) in the 'Files' tab when switching between commits.

This commit is contained in:
Johan Wångsell 2025-06-04 09:54:11 +02:00
parent f716c5ee1e
commit 633242bf22
2 changed files with 56 additions and 2 deletions

View file

@ -8,7 +8,7 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.RevisionFileTreeView"
x:Name="ThisControl">
<v:RevisionFileRowsListBox ItemsSource="{Binding #ThisControl.Rows}"
<v:RevisionFileRowsListBox x:Name="RevisionFileRowsListBox" ItemsSource="{Binding #ThisControl.Rows}"
Background="Transparent"
SelectionMode="Single"
SelectionChanged="OnRowsSelectionChanged"

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
@ -9,6 +9,7 @@ using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.VisualTree;
using SourceGit.ViewModels;
namespace SourceGit.Views
{
@ -249,6 +250,17 @@ namespace SourceGit.Views
if (change.Property == RevisionProperty)
{
var selectedNode = _revisionFileRowsListBox?.SelectedItem as RevisionFileTreeNode;
var expandedObjects = new List<Models.Object>();
foreach (var node in _rows)
{
if (node.IsExpanded)
{
expandedObjects.Add(node.Backend);
}
}
_tree.Clear();
_rows.Clear();
_searchResult.Clear();
@ -280,10 +292,51 @@ namespace SourceGit.Views
var topTree = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(topTree, _tree, 0);
_rows.AddRange(topTree);
_revisionFileRowsListBox ??= this.Find<RevisionFileRowsListBox>("RevisionFileRowsListBox");
if (_revisionFileRowsListBox is { IsArrangeValid: true })
{
RestoreTreeState(expandedObjects, selectedNode);
}
GC.Collect();
}
}
private void RestoreTreeState(List<Models.Object> expandedObjects, RevisionFileTreeNode selectedNode)
{
for (int i = 0; i < _rows.Count; i++)
{
var revisionFileTreeNode = _rows[i];
if (!revisionFileTreeNode.IsFolder)
continue;
if (expandedObjects.FirstOrDefault(o => o.SHA == revisionFileTreeNode.Backend.SHA || o.Path == revisionFileTreeNode.Backend.Path) != null)
{
ToggleNodeIsExpanded(revisionFileTreeNode);
}
}
if (selectedNode != null)
{
foreach (var node in _rows)
{
if (node.Backend.SHA != selectedNode.Backend.SHA && node.Backend.Path != selectedNode.Backend.Path)
continue;
selectedNode = node;
break;
}
}
if (_revisionFileRowsListBox != null)
{
_revisionFileRowsListBox.SelectedItem = selectedNode;
}
}
private void OnTreeNodeContextRequested(object sender, ContextRequestedEventArgs e)
{
if (DataContext is ViewModels.CommitDetail vm &&
@ -372,5 +425,6 @@ namespace SourceGit.Views
private AvaloniaList<ViewModels.RevisionFileTreeNode> _rows = [];
private bool _disableSelectionChangingEvent = false;
private List<ViewModels.RevisionFileTreeNode> _searchResult = [];
private RevisionFileRowsListBox _revisionFileRowsListBox;
}
}