fix: force re-create the tree instead of only rebuild the source for the tree (#157)

This commit is contained in:
leo 2024-06-02 14:06:27 +08:00
parent 9d88ae466f
commit f1f54bf6fe
2 changed files with 62 additions and 55 deletions

View file

@ -3,41 +3,33 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ChangeCollectionView"
x:Name="me">
<TreeDataGrid x:Name="tree"
AutoDragDropRows="False"
ShowColumnHeaders="False"
CanUserResizeColumns="False"
CanUserSortColumns="False"
ScrollViewer.BringIntoViewOnFocusChange="True">
<TreeDataGrid.Resources>
x:Name="ThisControl">
<UserControl.Resources>
<DataTemplate x:Key="TreeModeTemplate" DataType="m:FileTreeNode">
<Grid HorizontalAlignment="Stretch" Height="24" ColumnDefinitions="Auto,*">
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="{Binding #ThisControl.IsWorkingCopyChange}" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="ListModeTemplate" DataType="m:Change">
<StackPanel Orientation="Horizontal">
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #ThisControl.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="GridModeTemplate" DataType="m:Change">
<StackPanel Orientation="Horizontal">
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #ThisControl.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0"/>
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Foreground="{DynamicResource Brush.FG2}"/>
</StackPanel>
</DataTemplate>
</TreeDataGrid.Resources>
</TreeDataGrid>
</UserControl.Resources>
</UserControl>

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Controls.Templates;
using Avalonia.Interactivity;
namespace SourceGit.Views
@ -78,11 +79,10 @@ namespace SourceGit.Views
private void UpdateSource()
{
if (tree.Source is IDisposable disposable)
{
if (Content is TreeDataGrid tree && tree.Source is IDisposable disposable)
disposable.Dispose();
tree.Source = null;
}
Content = null;
var changes = Changes;
if (changes == null)
@ -92,12 +92,13 @@ namespace SourceGit.Views
if (viewMode == Models.ChangeViewMode.Tree)
{
var filetree = Models.FileTreeNode.Build(changes, true);
var template = this.FindResource("TreeModeTemplate") as IDataTemplate;
var source = new HierarchicalTreeDataGridSource<Models.FileTreeNode>(filetree)
{
Columns =
{
new HierarchicalExpanderColumn<Models.FileTreeNode>(
new TemplateColumn<Models.FileTreeNode>(null, "TreeModeTemplate", null, GridLength.Auto),
new TemplateColumn<Models.FileTreeNode>(null, template, null, GridLength.Auto),
x => x.Children,
x => x.Children.Count > 0,
x => x.IsExpanded)
@ -111,24 +112,25 @@ namespace SourceGit.Views
{
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<Models.FileTreeNode> model)
{
var selection = new List<Models.Change>();
var selected = new List<Models.Change>();
foreach (var c in model.SelectedItems)
CollectChangesInNode(selection, c);
CollectChangesInNode(selected, c);
_isSelecting = true;
SetCurrentValue(SelectedChangesProperty, selection);
SetCurrentValue(SelectedChangesProperty, selected);
_isSelecting = false;
}
};
source.Selection = selection;
tree.Source = source;
CreateTreeDataGrid(source);
}
else if (viewMode == Models.ChangeViewMode.List)
{
var template = this.FindResource("ListModeTemplate") as IDataTemplate;
var source = new FlatTreeDataGridSource<Models.Change>(changes)
{
Columns = { new TemplateColumn<Models.Change>(null, "ListModeTemplate", null, GridLength.Auto) }
Columns = { new TemplateColumn<Models.Change>(null, template, null, GridLength.Auto) }
};
var selection = new Models.TreeDataGridSelectionModel<Models.Change>(source, null);
@ -138,24 +140,25 @@ namespace SourceGit.Views
{
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<Models.Change> model)
{
var selection = new List<Models.Change>();
var selected = new List<Models.Change>();
foreach (var c in model.SelectedItems)
selection.Add(c);
selected.Add(c);
_isSelecting = true;
SetCurrentValue(SelectedChangesProperty, selection);
SetCurrentValue(SelectedChangesProperty, selected);
_isSelecting = false;
}
};
source.Selection = selection;
tree.Source = source;
CreateTreeDataGrid(source);
}
else
{
var template = this.FindResource("GridModeTemplate") as IDataTemplate;
var source = new FlatTreeDataGridSource<Models.Change>(changes)
{
Columns = { new TemplateColumn<Models.Change>(null, "GridModeTemplate", null, GridLength.Auto) },
Columns = { new TemplateColumn<Models.Change>(null, template, null, GridLength.Auto) },
};
var selection = new Models.TreeDataGridSelectionModel<Models.Change>(source, null);
@ -165,24 +168,28 @@ namespace SourceGit.Views
{
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<Models.Change> model)
{
var selection = new List<Models.Change>();
var selected = new List<Models.Change>();
foreach (var c in model.SelectedItems)
selection.Add(c);
selected.Add(c);
_isSelecting = true;
SetCurrentValue(SelectedChangesProperty, selection);
SetCurrentValue(SelectedChangesProperty, selected);
_isSelecting = false;
}
};
source.Selection = selection;
tree.Source = source;
CreateTreeDataGrid(source);
}
}
private void UpdateSelected()
{
if (_isSelecting || tree.Source == null)
if (_isSelecting || Content == null)
return;
var tree = Content as TreeDataGrid;
if (tree == null)
return;
_isSelecting = true;
@ -212,17 +219,25 @@ namespace SourceGit.Views
CollectSelectedNodeByChange(nodes, node as Models.FileTreeNode, set);
if (nodes.Count == 0)
{
treeSelection.Clear();
}
else
{
treeSelection.Select(nodes);
}
}
_isSelecting = false;
}
private void CreateTreeDataGrid(ITreeDataGridSource source)
{
Content = new TreeDataGrid()
{
AutoDragDropRows = false,
ShowColumnHeaders = false,
CanUserResizeColumns = false,
CanUserSortColumns = false,
Source = source,
};
}
private void CollectChangesInNode(List<Models.Change> outs, Models.FileTreeNode node)
{
if (node.IsFolder)