Skip to content

Commit

Permalink
πŸ› fix(Treeview): conflict between OnInput and ValueChanged (#586)
Browse files Browse the repository at this point in the history
* πŸ› fix(Treeview): conflict between OnInput and ValueChanged

* πŸ› fix(Treeview): a deadlock occurs when the key value is Guid.Empty
  • Loading branch information
capdiem authored Apr 1, 2024
1 parent 00ac5b9 commit 0fb02f8
Showing 1 changed file with 45 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,12 @@ public partial class BTreeview<TItem, TKey> : ITreeview<TItem, TKey> where TKey
public string ExpandIcon { get; set; } = "$subgroup";

[Parameter]
[Obsolete("Use OnSelectUpdate instead.")]
public EventCallback<List<TItem>> OnInput { get; set; }

[Parameter]
public EventCallback<List<TItem>> OnSelectUpdate { get; set; }

[Parameter]
public EventCallback<List<TItem>> OnActiveUpdate { get; set; }

Expand Down Expand Up @@ -243,7 +247,8 @@ public async Task EmitActiveAsync()
{
await ActiveChanged.InvokeAsync(active.Select(ItemKey).ToList());
}
else

if (!ActiveChanged.HasDelegate && !OnActiveUpdate.HasDelegate)
{
StateHasChanged();
}
Expand All @@ -270,7 +275,8 @@ public async Task EmitOpenAsync()
{
await OpenChanged.InvokeAsync(open.Select(ItemKey).ToList());
}
else

if (!OpenChanged.HasDelegate && !OnOpenUpdate.HasDelegate)
{
StateHasChanged();
}
Expand All @@ -291,12 +297,12 @@ private void UpdateSelected(TKey key, bool isSelected, bool updateByValue)

if (updateByValue && SelectionType == SelectionType.LeafButIndependentParent)
{
UpdateParentSelected(nodeState.Parent);
UpdateParentSelected(nodeState);
}
else if (SelectionType is SelectionType.Leaf or SelectionType.LeafButIndependentParent)
{
UpdateChildrenSelected(nodeState.Children, nodeState.IsSelected);
UpdateParentSelected(nodeState.Parent);
UpdateParentSelected(nodeState);
}
}

Expand All @@ -312,15 +318,18 @@ public async Task EmitSelectedAsync()
return r.IsSelected && !r.Children.Any();
}).Select(r => r.Item).ToList();

if (ValueChanged.HasDelegate)
var onSelectUpdate = OnSelectUpdate.HasDelegate ? OnSelectUpdate : OnInput;
if (onSelectUpdate.HasDelegate)
{
await ValueChanged.InvokeAsync(selected.Select(ItemKey).ToList());
_ = onSelectUpdate.InvokeAsync(selected);
}
else if (OnInput.HasDelegate)

if (ValueChanged.HasDelegate)
{
await OnInput.InvokeAsync(selected);
await ValueChanged.InvokeAsync(selected.Select(ItemKey).ToList());
}
else

if (!ValueChanged.HasDelegate && !onSelectUpdate.HasDelegate)
{
StateHasChanged();
}
Expand All @@ -334,11 +343,32 @@ public void RebuildTree()
BuildTree(Items, default);
}

private void UpdateParentSelected(TKey? parent, bool isIndeterminate = false)
private NodeState<TItem, TKey>[] GetParents(NodeState<TItem, TKey> node)
{
if (parent == null) return;
var parents = new List<NodeState<TItem, TKey>>();
var parent = node.Parent;
var parentKeys = new List<TKey>();
while (parent != null && !parentKeys.Contains(parent))
{
parentKeys.Add(parent);
if (Nodes.TryGetValue(parent, out var parentNode))
{
parents.Add(parentNode);
parent = parentNode.Parent;
}
else
{
break;
}
}

return parents.ToArray();
}

if (Nodes.TryGetValue(parent, out var nodeState))
private void UpdateParentSelected(NodeState<TItem, TKey> node, bool isIndeterminate = false)
{
var parents = GetParents(node);
foreach (var nodeState in parents)
{
if (SelectionType == SelectionType.LeafButIndependentParent)
{
Expand All @@ -353,9 +383,9 @@ private void UpdateParentSelected(TKey? parent, bool isIndeterminate = false)
else
{
var children = Nodes
.Where(r => nodeState.Children.Contains(r.Key))
.Select(r => r.Value)
.ToList();
.Where(r => nodeState.Children.Contains(r.Key))
.Select(r => r.Value)
.ToList();

if (children.All(r => r.IsSelected))
{
Expand All @@ -373,8 +403,6 @@ private void UpdateParentSelected(TKey? parent, bool isIndeterminate = false)
nodeState.IsIndeterminate = true;
}
}

UpdateParentSelected(nodeState.Parent, nodeState.IsIndeterminate);
}
}

Expand Down

0 comments on commit 0fb02f8

Please sign in to comment.