Skip to content

Commit

Permalink
feat: Implemented SelectedItemsVector and SelectedTreeNodeVector
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Sep 11, 2020
1 parent bb40a3d commit de9e4a3
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 262 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation.Collections;

namespace Microsoft.UI.Xaml.Controls
{
//// Similiar to SelectedNodesVector above, we need to make decisions before the item is inserted or removed.
//// we can't use vector change events because the event already happened when event hander gets called.
internal class SelectedItemsVector : ObservableVector<object>
{
private TreeViewViewModel m_viewModel;

public void SetViewModel(TreeViewViewModel viewModel)
{
m_viewModel = viewModel;
}

internal void Append(object item) => InsertAt(Count, item);

internal void InsertAt(int index, object item)
{
if (!Contains(item))
{
GetVectorInnerImpl().Insert(index, item);

// Keep SelectedNodes and SelectedItems in sync
var viewModel = m_viewModel;
if (viewModel != null)
{
var selectedNodes = viewModel.SelectedNodes;
if (selectedNodes.Count != Count)
{
var listControl = viewModel.ListControl;
if (listControl != null)
{
var node = listControl.NodeFromItem(item);
if (node != null)
{
selectedNodes.Insert(index, node);
}
}
}
}
}
}

internal void SetAt(int index, object item)
{
RemoveAt(index);
InsertAt(index, item);
}

public override void RemoveAt(int index)
{
GetVectorInnerImpl().RemoveAt(index);

// Keep SelectedNodes and SelectedItems in sync
var viewModel = m_viewModel;
if (viewModel != null)
{
var selectedNodes = viewModel.SelectedNodes;
if (Count != selectedNodes.Count)
{
selectedNodes.RemoveAt(index);
}
}
}

internal void RemoveAtEnd() => RemoveAt(Count - 1);

internal void ReplaceAll(IEnumerable<object> items)
{
Clear();

foreach (var node in items)
{
Append(node);
}
}

public override void Clear()
{
while (Count > 0)
{
RemoveAtEnd();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System.Collections.Generic;
using Microsoft.UI.Xaml.Controls;
using Windows.Foundation.Collections;

namespace Microsoft.UI.Xaml.Controls
{
// Need to update node selection states on UI before vector changes.
// Listen on vector change events don't solve the problem because the event already happened when the event handler gets called.
// i.e. the node is alreay gone when we get to ItemRemoved callback.
internal class SelectedTreeNodeVector : ObservableVector<TreeViewNode>
{
TreeViewViewModel m_viewModel = null;

private void UpdateSelection(TreeViewNode node, TreeNodeSelectionState state)
{
if (node.SelectionState != state)
{
var viewModel = m_viewModel;

if (viewModel != null)
{
viewModel.UpdateSelection(node, state);
viewModel.NotifyContainerOfSelectionChange(node, state);
}
}
}

public void SetViewModel(TreeViewViewModel viewModel)
{
m_viewModel = viewModel;
}

internal void Append(TreeViewNode node) => InsertAt(Count, node);

public override void Add(TreeViewNode node) => Append(node);

internal void InsertAt(int index, TreeViewNode node)
{
if (!Contains(node))
{
// UpdateSelection will call InsertAtCore
UpdateSelection(node, TreeNodeSelectionState.Selected);
}
}

public override void Insert(int index, TreeViewNode node) => InsertAt(index, node);

internal void SetAt(int index, TreeViewNode node)
{
RemoveAt(index);
InsertAt(index, node);
}

public override TreeViewNode this[int index]
{
get => base[index];
set => SetAt(index, value);
}

public override void RemoveAt(int index)
{
var inner = GetVectorInnerImpl();
var oldNode = inner[index];
// UpdateNodeSelection will call RemoveAtCore
UpdateSelection(oldNode, TreeNodeSelectionState.UnSelected);
}

internal void RemoveAtEnd() => RemoveAt(Count - 1);

internal void ReplaceAll(IEnumerable<TreeViewNode> nodes)
{
Clear();

foreach (var node in nodes)
{
Append(node);
}
}

public override void Clear()
{
while (Count > 0)
{
RemoveAtEnd();
}
}

// Default write methods will trigger TreeView visual updates.
// If you want to update vector content without notifying TreeViewNodes, use "core" version of the methods.
internal void InsertAtCore(int index, TreeViewNode node)
{
GetVectorInnerImpl().Insert(index, node);

// Keep SelectedItems and SelectedNodes in sync
var viewModel = m_viewModel;
if (viewModel != null)
{
var selectedItems = viewModel.SelectedItems;
if (selectedItems.Count != Count)
{
var listControl = viewModel.ListControl;
var item = listControl?.ItemFromNode(node);
if (item != null)
{
selectedItems.Insert(index, item);
}
}
}
}

internal void RemoveAtCore(int index)
{
GetVectorInnerImpl().RemoveAt(index);

// Keep SelectedItems and SelectedNodes in sync
var viewModel = m_viewModel;
if (viewModel != null)
{
var selectedItems = viewModel.SelectedItems;
if (Count != selectedItems.Count)
{
selectedItems.RemoveAt(index);
}
}
}
}
}
Loading

0 comments on commit de9e4a3

Please sign in to comment.