|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Windows.Controls;
using System.Windows.Input;
namespace Microsoft.VisualStudio.LanguageServices.ValueTracking;
/// <summary>
/// Interaction logic for ValueTrackingTree.xaml
/// </summary>
internal partial class ValueTrackingTree : UserControl
{
private readonly ValueTrackingTreeViewModel _viewModel;
public ValueTrackingTree(ValueTrackingTreeViewModel viewModel)
{
DataContext = _viewModel = viewModel;
InitializeComponent();
}
private void ValueTrackingTree_PreviewKeyDown(object sender, KeyEventArgs e)
{
e.Handled = e.Handled || e.Key switch
{
Key.Down => TrySelectItem(GetNextItem(expandNode: false), navigate: true),
Key.Up => TrySelectItem(GetPreviousItem(), navigate: true),
Key.F8 => e.KeyboardDevice.Modifiers == ModifierKeys.Shift ? TrySelectItem(GetPreviousItem(), navigate: true) : TrySelectItem(GetNextItem(expandNode: true), navigate: true),
Key.Enter => TrySelectItem(ValueTrackingTreeView.SelectedItem as TreeViewItemBase, navigate: true),
Key.Right => TrySetExpanded(ValueTrackingTreeView.SelectedItem as TreeViewItemBase, true),
Key.Left => TrySetExpanded(ValueTrackingTreeView.SelectedItem as TreeViewItemBase, false),
Key.Space => TryToggleExpanded(ValueTrackingTreeView.SelectedItem as TreeViewItemBase),
_ => false
};
// Local Functions
bool TrySelectItem(TreeViewItemBase? node, bool navigate)
{
if (node is null)
{
return false;
}
SelectItem(node, navigate);
return true;
}
bool TrySetExpanded(TreeViewItemBase? node, bool expanded)
{
if (node is null)
{
return false;
}
node.IsNodeExpanded = expanded;
return true;
}
bool TryToggleExpanded(TreeViewItemBase? node)
{
return TrySetExpanded(node, node is null ? false : !node.IsNodeExpanded);
}
}
private void ValueTrackingTree_MouseDoubleClickPreview(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left)
{
return;
}
if (sender is TreeViewItemBase viewModel)
{
SelectItem(viewModel, true);
e.Handled = true;
}
else if (sender is TreeView)
{
SelectItem(_viewModel.SelectedItem, true);
e.Handled = true;
}
}
private void SelectItem(TreeViewItemBase? item, bool navigate = false)
{
_viewModel.SelectedItem = item;
if (navigate && item is TreeItemViewModel navigatableItem)
{
navigatableItem.NavigateTo();
}
}
private TreeViewItemBase GetNextItem(bool expandNode)
{
if (ValueTrackingTreeView.SelectedItem is null)
{
return (TreeViewItemBase)ValueTrackingTreeView.Items[0];
}
var item = (TreeViewItemBase)ValueTrackingTreeView.SelectedItem;
if (expandNode)
{
item.IsNodeExpanded = true;
}
return item.GetNextInTree();
}
private TreeViewItemBase GetPreviousItem()
{
if (ValueTrackingTreeView.SelectedItem is null)
{
return (TreeViewItemBase)ValueTrackingTreeView.Items[^1];
}
var item = (TreeViewItemBase)ValueTrackingTreeView.SelectedItem;
return item.GetPreviousInTree();
}
private void ValueTrackingTree_SelectedItemChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<object> e)
{
_viewModel.SelectedItem = ValueTrackingTreeView.SelectedItem as TreeViewItemBase;
}
}
|