diff --git a/src/App.axaml b/src/App.axaml
index d73ea45d..6e485f3a 100644
--- a/src/App.axaml
+++ b/src/App.axaml
@@ -20,7 +20,6 @@
-
diff --git a/src/Models/TreeDataGridSelectionModel.cs b/src/Models/TreeDataGridSelectionModel.cs
deleted file mode 100644
index be9d7d7c..00000000
--- a/src/Models/TreeDataGridSelectionModel.cs
+++ /dev/null
@@ -1,462 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.Models.TreeDataGrid;
-using Avalonia.Controls.Primitives;
-using Avalonia.Controls.Selection;
-using Avalonia.Input;
-
-namespace SourceGit.Models
-{
- public class TreeDataGridSelectionModel : TreeSelectionModelBase,
- ITreeDataGridRowSelectionModel,
- ITreeDataGridSelectionInteraction
- where TModel : class
- {
- private static readonly Point s_InvalidPoint = new(double.NegativeInfinity, double.NegativeInfinity);
-
- private readonly ITreeDataGridSource _source;
- private EventHandler _viewSelectionChanged;
- private EventHandler _rowDoubleTapped;
- private Point _pressedPoint = s_InvalidPoint;
- private bool _raiseViewSelectionChanged;
- private Func> _childrenGetter;
-
- public TreeDataGridSelectionModel(ITreeDataGridSource source, Func> childrenGetter)
- : base(source.Items)
- {
- _source = source;
- _childrenGetter = childrenGetter;
-
- SelectionChanged += (s, e) =>
- {
- if (!IsSourceCollectionChanging)
- _viewSelectionChanged?.Invoke(this, e);
- else
- _raiseViewSelectionChanged = true;
- };
- }
-
- public void Select(IEnumerable items)
- {
- using (BatchUpdate())
- {
- Clear();
-
- foreach (var selected in items)
- {
- var idx = GetModelIndex(_source.Items, selected, IndexPath.Unselected);
- if (!idx.Equals(IndexPath.Unselected))
- Select(idx);
- }
- }
- }
-
- event EventHandler ITreeDataGridSelectionInteraction.SelectionChanged
- {
- add => _viewSelectionChanged += value;
- remove => _viewSelectionChanged -= value;
- }
-
- public event EventHandler RowDoubleTapped
- {
- add => _rowDoubleTapped += value;
- remove => _rowDoubleTapped -= value;
- }
-
- IEnumerable ITreeDataGridSelection.Source
- {
- get => Source;
- set => Source = value;
- }
-
- bool ITreeDataGridSelectionInteraction.IsRowSelected(IRow rowModel)
- {
- if (rowModel is IModelIndexableRow indexable)
- return IsSelected(indexable.ModelIndexPath);
- return false;
- }
-
- bool ITreeDataGridSelectionInteraction.IsRowSelected(int rowIndex)
- {
- if (rowIndex >= 0 && rowIndex < _source.Rows.Count)
- {
- if (_source.Rows[rowIndex] is IModelIndexableRow indexable)
- return IsSelected(indexable.ModelIndexPath);
- }
-
- return false;
- }
-
- void ITreeDataGridSelectionInteraction.OnKeyDown(TreeDataGrid sender, KeyEventArgs e)
- {
- if (sender.RowsPresenter is null)
- return;
-
- if (!e.Handled)
- {
- var ctrl = e.KeyModifiers.HasFlag(KeyModifiers.Control);
- if (e.Key == Key.A && ctrl && !SingleSelect)
- {
- using (BatchUpdate())
- {
- Clear();
-
- int num = _source.Rows.Count;
- for (int i = 0; i < num; ++i)
- {
- var m = _source.Rows.RowIndexToModelIndex(i);
- Select(m);
- }
- }
- e.Handled = true;
- }
-
- var direction = e.Key.ToNavigationDirection();
- var shift = e.KeyModifiers.HasFlag(KeyModifiers.Shift);
- if (direction.HasValue)
- {
- var anchorRowIndex = _source.Rows.ModelIndexToRowIndex(AnchorIndex);
- sender.RowsPresenter.BringIntoView(anchorRowIndex);
-
- var anchor = sender.TryGetRow(anchorRowIndex);
- if (anchor is not null && !ctrl)
- {
- e.Handled = TryKeyExpandCollapse(sender, direction.Value, anchor);
- }
-
- if (!e.Handled && (!ctrl || shift))
- {
- e.Handled = MoveSelection(sender, direction.Value, shift, anchor);
- }
-
- if (!e.Handled && direction == NavigationDirection.Left
- && anchor?.Rows is HierarchicalRows hierarchicalRows && anchorRowIndex > 0)
- {
- var newIndex = hierarchicalRows.GetParentRowIndex(AnchorIndex);
- UpdateSelection(sender, newIndex, true);
- FocusRow(sender, sender.RowsPresenter.BringIntoView(newIndex));
- }
-
- if (!e.Handled && direction == NavigationDirection.Right
- && anchor?.Rows is HierarchicalRows hierarchicalRows2 && hierarchicalRows2[anchorRowIndex].IsExpanded)
- {
- var newIndex = anchorRowIndex + 1;
- UpdateSelection(sender, newIndex, true);
- sender.RowsPresenter.BringIntoView(newIndex);
- }
- }
- }
- }
-
- void ITreeDataGridSelectionInteraction.OnPointerPressed(TreeDataGrid sender, PointerPressedEventArgs e)
- {
- if (!e.Handled &&
- e.Pointer.Type == PointerType.Mouse &&
- e.Source is Control source &&
- sender.TryGetRow(source, out var row) &&
- _source.Rows.RowIndexToModelIndex(row.RowIndex) is { } modelIndex)
- {
- if (!IsSelected(modelIndex))
- {
- PointerSelect(sender, row, e);
- _pressedPoint = s_InvalidPoint;
- }
- else
- {
- var point = e.GetCurrentPoint(sender);
- if (point.Properties.IsRightButtonPressed)
- {
- _pressedPoint = s_InvalidPoint;
- return;
- }
-
- if (e.KeyModifiers == KeyModifiers.Control)
- {
- Deselect(modelIndex);
- }
- else if (e.ClickCount % 2 == 0)
- {
- var focus = _source.Rows[row.RowIndex];
- if (focus is IExpander expander && HasChildren(focus))
- expander.IsExpanded = !expander.IsExpanded;
- else
- _rowDoubleTapped?.Invoke(this, e);
-
- e.Handled = true;
- }
- else if (sender.RowSelection.Count > 1)
- {
- using (BatchUpdate())
- {
- Clear();
- Select(modelIndex);
- }
- }
-
- _pressedPoint = s_InvalidPoint;
- }
- }
- else
- {
- if (!sender.TryGetRow(e.Source as Control, out var test))
- Clear();
-
- _pressedPoint = e.GetPosition(sender);
- }
- }
-
- void ITreeDataGridSelectionInteraction.OnPointerReleased(TreeDataGrid sender, PointerReleasedEventArgs e)
- {
- if (!e.Handled &&
- _pressedPoint != s_InvalidPoint &&
- e.Source is Control source &&
- sender.TryGetRow(source, out var row) &&
- _source.Rows.RowIndexToModelIndex(row.RowIndex) is { } modelIndex)
- {
- if (!IsSelected(modelIndex))
- {
- var p = e.GetPosition(sender);
- if (Math.Abs(p.X - _pressedPoint.X) <= 3 || Math.Abs(p.Y - _pressedPoint.Y) <= 3)
- PointerSelect(sender, row, e);
- }
- }
- }
-
- protected override void OnSourceCollectionChangeFinished()
- {
- if (_raiseViewSelectionChanged)
- {
- _viewSelectionChanged?.Invoke(this, EventArgs.Empty);
- _raiseViewSelectionChanged = false;
- }
- }
-
- private void PointerSelect(TreeDataGrid sender, TreeDataGridRow row, PointerEventArgs e)
- {
- var point = e.GetCurrentPoint(sender);
-
- var commandModifiers = TopLevel.GetTopLevel(sender)?.PlatformSettings?.HotkeyConfiguration.CommandModifiers;
- var toggleModifier = commandModifiers is not null && e.KeyModifiers.HasFlag(commandModifiers);
- var isRightButton = point.Properties.PointerUpdateKind is PointerUpdateKind.RightButtonPressed or
- PointerUpdateKind.RightButtonReleased;
-
- UpdateSelection(
- sender,
- row.RowIndex,
- select: true,
- rangeModifier: e.KeyModifiers.HasFlag(KeyModifiers.Shift),
- toggleModifier: toggleModifier,
- rightButton: isRightButton);
- e.Handled = true;
- }
-
- private void UpdateSelection(TreeDataGrid treeDataGrid, int rowIndex, bool select = true, bool rangeModifier = false, bool toggleModifier = false, bool rightButton = false)
- {
- var modelIndex = _source.Rows.RowIndexToModelIndex(rowIndex);
- if (modelIndex == default)
- return;
-
- var mode = SingleSelect ? SelectionMode.Single : SelectionMode.Multiple;
- var multi = (mode & SelectionMode.Multiple) != 0;
- var toggle = (toggleModifier || (mode & SelectionMode.Toggle) != 0);
- var range = multi && rangeModifier;
-
- if (!select)
- {
- if (IsSelected(modelIndex) && !treeDataGrid.QueryCancelSelection())
- Deselect(modelIndex);
- }
- else if (rightButton)
- {
- if (IsSelected(modelIndex) == false && !treeDataGrid.QueryCancelSelection())
- SelectedIndex = modelIndex;
- }
- else if (range)
- {
- if (!treeDataGrid.QueryCancelSelection())
- {
- var anchor = RangeAnchorIndex;
- var i = Math.Max(_source.Rows.ModelIndexToRowIndex(anchor), 0);
- var step = i < rowIndex ? 1 : -1;
-
- using (BatchUpdate())
- {
- Clear();
-
- while (true)
- {
- var m = _source.Rows.RowIndexToModelIndex(i);
- Select(m);
- anchor = m;
- if (i == rowIndex)
- break;
- i += step;
- }
- }
- }
- }
- else if (multi && toggle)
- {
- if (!treeDataGrid.QueryCancelSelection())
- {
- if (IsSelected(modelIndex) == true)
- Deselect(modelIndex);
- else
- Select(modelIndex);
- }
- }
- else if (toggle)
- {
- if (!treeDataGrid.QueryCancelSelection())
- SelectedIndex = (SelectedIndex == modelIndex) ? -1 : modelIndex;
- }
- else if (SelectedIndex != modelIndex || Count > 1)
- {
- if (!treeDataGrid.QueryCancelSelection())
- SelectedIndex = modelIndex;
- }
- }
-
- private bool TryKeyExpandCollapse(TreeDataGrid treeDataGrid, NavigationDirection direction, TreeDataGridRow focused)
- {
- if (treeDataGrid.RowsPresenter is null || focused.RowIndex < 0)
- return false;
-
- var row = _source.Rows[focused.RowIndex];
-
- if (row is IExpander expander)
- {
- if (direction == NavigationDirection.Right && !expander.IsExpanded)
- {
- expander.IsExpanded = true;
- return true;
- }
- else if (direction == NavigationDirection.Left && expander.IsExpanded)
- {
- expander.IsExpanded = false;
- return true;
- }
- }
-
- return false;
- }
-
- private bool MoveSelection(TreeDataGrid treeDataGrid, NavigationDirection direction, bool rangeModifier, TreeDataGridRow focused)
- {
- if (treeDataGrid.RowsPresenter is null || _source.Columns.Count == 0 || _source.Rows.Count == 0)
- return false;
-
- var currentRowIndex = focused?.RowIndex ?? _source.Rows.ModelIndexToRowIndex(SelectedIndex);
- int newRowIndex;
-
- if (direction == NavigationDirection.First || direction == NavigationDirection.Last)
- {
- newRowIndex = direction == NavigationDirection.First ? 0 : _source.Rows.Count - 1;
- }
- else
- {
- (var x, var y) = direction switch
- {
- NavigationDirection.Up => (0, -1),
- NavigationDirection.Down => (0, 1),
- NavigationDirection.Left => (-1, 0),
- NavigationDirection.Right => (1, 0),
- _ => (0, 0)
- };
-
- newRowIndex = Math.Max(0, Math.Min(currentRowIndex + y, _source.Rows.Count - 1));
- }
-
- if (newRowIndex != currentRowIndex)
- UpdateSelection(treeDataGrid, newRowIndex, true, rangeModifier);
-
- if (newRowIndex != currentRowIndex)
- {
- treeDataGrid.RowsPresenter?.BringIntoView(newRowIndex);
- FocusRow(treeDataGrid, treeDataGrid.TryGetRow(newRowIndex));
- return true;
- }
- else
- {
- return false;
- }
- }
-
- private static void FocusRow(TreeDataGrid owner, Control control)
- {
- if (!owner.TryGetRow(control, out var row) || row.CellsPresenter is null)
- return;
-
- // Get the column index of the currently focused cell if possible: we'll try to focus the
- // same column in the new row.
- if (TopLevel.GetTopLevel(owner)?.FocusManager is { } focusManager &&
- focusManager.GetFocusedElement() is Control currentFocus &&
- owner.TryGetCell(currentFocus, out var currentCell) &&
- row.TryGetCell(currentCell.ColumnIndex) is { } newCell &&
- newCell.Focusable)
- {
- newCell.Focus();
- }
- else
- {
- // Otherwise, just focus the first focusable cell in the row.
- foreach (var cell in row.CellsPresenter.GetRealizedElements())
- {
- if (cell.Focusable)
- {
- cell.Focus();
- break;
- }
- }
- }
- }
-
- protected override IEnumerable GetChildren(TModel node)
- {
- if (node == null)
- return null;
-
- return _childrenGetter?.Invoke(node);
- }
-
- private IndexPath GetModelIndex(IEnumerable collection, TModel model, IndexPath parent)
- {
- int i = 0;
-
- foreach (var item in collection)
- {
- var index = parent.Append(i);
- if (item != null && item == model)
- return index;
-
- var children = GetChildren(item);
- if (children != null)
- {
- var findInChildren = GetModelIndex(children, model, index);
- if (!findInChildren.Equals(IndexPath.Unselected))
- return findInChildren;
- }
-
- i++;
- }
-
- return IndexPath.Unselected;
- }
-
- private bool HasChildren(IRow row)
- {
- var children = GetChildren(row.Model as TModel);
- if (children != null)
- {
- foreach (var c in children)
- return true;
- }
-
- return false;
- }
- }
-}
diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml
index 78f3bbca..9d63184a 100644
--- a/src/Resources/Styles.axaml
+++ b/src/Resources/Styles.axaml
@@ -1093,6 +1093,33 @@
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Views/ChangeCollectionView.axaml.cs b/src/Views/ChangeCollectionView.axaml.cs
index c9ae72b2..beb5e60b 100644
--- a/src/Views/ChangeCollectionView.axaml.cs
+++ b/src/Views/ChangeCollectionView.axaml.cs
@@ -2,22 +2,51 @@ using System;
using System.Collections.Generic;
using Avalonia;
+using Avalonia.Collections;
using Avalonia.Controls;
-using Avalonia.Controls.Models.TreeDataGrid;
-using Avalonia.Controls.Templates;
+using Avalonia.Controls.Primitives;
+using Avalonia.Input;
using Avalonia.Interactivity;
+using Avalonia.VisualTree;
+
+using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Views
{
- public class ChangeTreeNode
+ public class ChangeTreeNode : ObservableObject
{
public string FullPath { get; set; } = string.Empty;
- public bool IsFolder { get; set; } = false;
- public bool IsExpanded { get; set; } = false;
+ public int Depth { get; private set; } = 0;
public Models.Change Change { get; set; } = null;
public List Children { get; set; } = new List();
- public static List Build(IList changes, bool expanded)
+ public bool IsFolder
+ {
+ get => Change == null;
+ }
+
+ public bool IsExpanded
+ {
+ get => _isExpanded;
+ set => SetProperty(ref _isExpanded, value);
+ }
+
+ public ChangeTreeNode(Models.Change c, int depth)
+ {
+ FullPath = c.Path;
+ Depth = depth;
+ Change = c;
+ IsExpanded = false;
+ }
+
+ public ChangeTreeNode(string path, bool isExpanded, int depth)
+ {
+ FullPath = path;
+ Depth = depth;
+ IsExpanded = isExpanded;
+ }
+
+ public static List Build(IList changes, HashSet folded)
{
var nodes = new List();
var folders = new Dictionary();
@@ -27,18 +56,13 @@ namespace SourceGit.Views
var sepIdx = c.Path.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1)
{
- nodes.Add(new ChangeTreeNode()
- {
- FullPath = c.Path,
- Change = c,
- IsFolder = false,
- IsExpanded = false
- });
+ nodes.Add(new ChangeTreeNode(c, 0));
}
else
{
ChangeTreeNode lastFolder = null;
var start = 0;
+ var depth = 0;
while (sepIdx != -1)
{
@@ -49,42 +73,29 @@ namespace SourceGit.Views
}
else if (lastFolder == null)
{
- lastFolder = new ChangeTreeNode()
- {
- FullPath = folder,
- IsFolder = true,
- IsExpanded = expanded
- };
+ lastFolder = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, lastFolder);
InsertFolder(nodes, lastFolder);
}
else
{
- var cur = new ChangeTreeNode()
- {
- FullPath = folder,
- IsFolder = true,
- IsExpanded = expanded
- };
+ var cur = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, cur);
InsertFolder(lastFolder.Children, cur);
lastFolder = cur;
}
start = sepIdx + 1;
+ depth++;
sepIdx = c.Path.IndexOf('/', start);
}
- lastFolder.Children.Add(new ChangeTreeNode()
- {
- FullPath = c.Path,
- Change = c,
- IsFolder = false,
- IsExpanded = false
- });
+ lastFolder.Children.Add(new ChangeTreeNode(c, depth));
}
}
+ Sort(nodes);
+
folders.Clear();
return nodes;
}
@@ -102,6 +113,68 @@ namespace SourceGit.Views
collection.Add(subFolder);
}
+
+ private static void Sort(List nodes)
+ {
+ foreach (var node in nodes)
+ {
+ if (node.IsFolder)
+ Sort(node.Children);
+ }
+
+ nodes.Sort((l, r) =>
+ {
+ if (l.IsFolder)
+ return r.IsFolder ? string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal) : -1;
+ return r.IsFolder ? 1 : string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal);
+ });
+ }
+
+ private bool _isExpanded = true;
+ }
+
+ public class ChangeCollectionAsTree
+ {
+ public List Tree { get; set; } = new List();
+ public AvaloniaList Rows { get; set; } = new AvaloniaList();
+ }
+
+ public class ChangeCollectionAsGrid
+ {
+ public AvaloniaList Changes { get; set; } = new AvaloniaList();
+ }
+
+ public class ChangeCollectionAsList
+ {
+ public AvaloniaList Changes { get; set; } = new AvaloniaList();
+ }
+
+ public class ChangeTreeNodeToggleButton : ToggleButton
+ {
+ protected override Type StyleKeyOverride => typeof(ToggleButton);
+
+ protected override void OnPointerPressed(PointerPressedEventArgs e)
+ {
+ if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed &&
+ DataContext is ChangeTreeNode { IsFolder: true } node)
+ {
+ var tree = this.FindAncestorOfType();
+ tree.ToggleNodeIsExpanded(node);
+ }
+
+ e.Handled = true;
+ }
+ }
+
+ public class ChangeCollectionContainer : ListBox
+ {
+ protected override Type StyleKeyOverride => typeof(ListBox);
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ if (e.Key != Key.Space)
+ base.OnKeyDown(e);
+ }
}
public partial class ChangeCollectionView : UserControl
@@ -115,13 +188,13 @@ namespace SourceGit.Views
set => SetValue(IsWorkingCopyChangeProperty, value);
}
- public static readonly StyledProperty SingleSelectProperty =
- AvaloniaProperty.Register(nameof(SingleSelect), true);
+ public static readonly StyledProperty SelectionModeProperty =
+ AvaloniaProperty.Register(nameof(SelectionMode), SelectionMode.Single);
- public bool SingleSelect
+ public SelectionMode SelectionMode
{
- get => GetValue(SingleSelectProperty);
- set => SetValue(SingleSelectProperty, value);
+ get => GetValue(SelectionModeProperty);
+ set => SetValue(SelectionModeProperty, value);
}
public static readonly StyledProperty ViewModeProperty =
@@ -160,171 +233,193 @@ namespace SourceGit.Views
remove { RemoveHandler(ChangeDoubleTappedEvent, value); }
}
- static ChangeCollectionView()
- {
- ViewModeProperty.Changed.AddClassHandler((c, e) => c.UpdateSource());
- ChangesProperty.Changed.AddClassHandler((c, e) => c.UpdateSource());
- SelectedChangesProperty.Changed.AddClassHandler((c, e) => c.UpdateSelected());
- }
-
public ChangeCollectionView()
{
InitializeComponent();
}
- private void UpdateSource()
+ public void ToggleNodeIsExpanded(ChangeTreeNode node)
{
- if (Content is TreeDataGrid tree && tree.Source is IDisposable disposable)
- disposable.Dispose();
-
- Content = null;
-
- var changes = Changes;
- if (changes == null || changes.Count == 0)
- return;
-
- var viewMode = ViewMode;
- if (viewMode == Models.ChangeViewMode.Tree)
+ if (_displayContext is ChangeCollectionAsTree tree)
{
- var filetree = ChangeTreeNode.Build(changes, true);
- var template = this.FindResource("TreeModeTemplate") as IDataTemplate;
- var source = new HierarchicalTreeDataGridSource(filetree)
+ _disableSelectionChangingEvent = true;
+ node.IsExpanded = !node.IsExpanded;
+
+ var depth = node.Depth;
+ var idx = tree.Rows.IndexOf(node);
+ if (idx == -1)
+ return;
+
+ if (node.IsExpanded)
{
- Columns =
+ var subrows = new List();
+ MakeTreeRows(subrows, node.Children);
+ tree.Rows.InsertRange(idx + 1, subrows);
+ }
+ else
+ {
+ var removeCount = 0;
+ for (int i = idx + 1; i < tree.Rows.Count; i++)
{
- new HierarchicalExpanderColumn(
- new TemplateColumn(null, template, null, GridLength.Auto),
- x => x.Children,
- x => x.Children.Count > 0,
- x => x.IsExpanded)
+ var row = tree.Rows[i];
+ if (row.Depth <= depth)
+ break;
+
+ removeCount++;
}
- };
+ tree.Rows.RemoveRange(idx + 1, removeCount);
+ }
- var selection = new Models.TreeDataGridSelectionModel(source, x => x.Children);
- selection.SingleSelect = SingleSelect;
- selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
- selection.SelectionChanged += (s, _) =>
- {
- if (!_isSelecting && s is Models.TreeDataGridSelectionModel model)
- {
- var selected = new List();
- foreach (var c in model.SelectedItems)
- CollectChangesInNode(selected, c);
-
- TrySetSelected(selected);
- }
- };
-
- source.Selection = selection;
- CreateTreeDataGrid(source);
- }
- else if (viewMode == Models.ChangeViewMode.List)
- {
- var template = this.FindResource("ListModeTemplate") as IDataTemplate;
- var source = new FlatTreeDataGridSource(changes)
- {
- Columns = { new TemplateColumn(null, template, null, GridLength.Auto) }
- };
-
- var selection = new Models.TreeDataGridSelectionModel(source, null);
- selection.SingleSelect = SingleSelect;
- selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
- selection.SelectionChanged += (s, _) =>
- {
- if (!_isSelecting && s is Models.TreeDataGridSelectionModel model)
- {
- var selected = new List();
- foreach (var c in model.SelectedItems)
- selected.Add(c);
-
- TrySetSelected(selected);
- }
- };
-
- source.Selection = selection;
- CreateTreeDataGrid(source);
- }
- else
- {
- var template = this.FindResource("GridModeTemplate") as IDataTemplate;
- var source = new FlatTreeDataGridSource(changes)
- {
- Columns = { new TemplateColumn(null, template, null, GridLength.Auto) },
- };
-
- var selection = new Models.TreeDataGridSelectionModel(source, null);
- selection.SingleSelect = SingleSelect;
- selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
- selection.SelectionChanged += (s, _) =>
- {
- if (!_isSelecting && s is Models.TreeDataGridSelectionModel model)
- {
- var selected = new List();
- foreach (var c in model.SelectedItems)
- selected.Add(c);
-
- TrySetSelected(selected);
- }
- };
-
- source.Selection = selection;
- CreateTreeDataGrid(source);
+ _disableSelectionChangingEvent = false;
}
}
- private void UpdateSelected()
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
- if (_isSelecting || Content == null)
- return;
+ base.OnPropertyChanged(change);
- var tree = Content as TreeDataGrid;
- if (tree == null)
- return;
-
- _isSelecting = true;
- var selected = SelectedChanges;
- if (tree.Source.Selection is Models.TreeDataGridSelectionModel changeSelection)
+ if (change.Property == ViewModeProperty || change.Property == ChangesProperty)
{
- if (selected == null || selected.Count == 0)
- changeSelection.Clear();
- else
- changeSelection.Select(selected);
- }
- else if (tree.Source.Selection is Models.TreeDataGridSelectionModel treeSelection)
- {
- if (selected == null || selected.Count == 0)
+ _disableSelectionChangingEvent = change.Property == ChangesProperty;
+ var changes = Changes;
+ if (changes == null || changes.Count == 0)
{
- treeSelection.Clear();
- _isSelecting = false;
+ Content = null;
+ _displayContext = null;
+ _disableSelectionChangingEvent = false;
return;
}
- var set = new HashSet