generic hierarchical control
This commit is contained in:
@@ -105,12 +105,12 @@
|
|||||||
Padding="4"
|
Padding="4"
|
||||||
BorderBrush="{DynamicResource BackgroundColor.Menu.SubCategory.Hover}"
|
BorderBrush="{DynamicResource BackgroundColor.Menu.SubCategory.Hover}"
|
||||||
BorderThickness="1">
|
BorderThickness="1">
|
||||||
<ScrollViewer x:Name="PART_CategoryScrollViewer"
|
<ScrollViewer x:Name="PART_ItemsScrollViewer"
|
||||||
MaxHeight="320"
|
MaxHeight="320"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Auto"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
PreviewMouseWheel="CategoryScrollViewer_PreviewMouseWheel">
|
PreviewMouseWheel="ItemsScrollViewer_PreviewMouseWheel">
|
||||||
<TreeView x:Name="PART_TreeView"
|
<TreeView x:Name="PART_TreeView"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using static C4IT.Logging.cLogManager;
|
|
||||||
|
|
||||||
namespace FasdDesktopUi.Basics.UserControls
|
namespace FasdDesktopUi.Basics.UserControls
|
||||||
{
|
{
|
||||||
@@ -22,7 +21,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
|
|
||||||
private TextBox searchTextBox;
|
private TextBox searchTextBox;
|
||||||
private TreeView treeViewControl;
|
private TreeView treeViewControl;
|
||||||
private ScrollViewer categoryScrollViewer;
|
private ScrollViewer itemsScrollViewer;
|
||||||
|
|
||||||
public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems;
|
public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems;
|
||||||
|
|
||||||
@@ -41,7 +40,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
EnsureTemplateParts();
|
EnsureTemplateParts();
|
||||||
if (treeViewControl != null)
|
if (treeViewControl != null)
|
||||||
treeViewControl.ItemsSource = VisibleItems;
|
treeViewControl.ItemsSource = VisibleItems;
|
||||||
UpdateDisplaySelection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region DependencyProperties
|
#region DependencyProperties
|
||||||
@@ -64,7 +62,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
{
|
{
|
||||||
control.RebuildLookup();
|
control.RebuildLookup();
|
||||||
control.ApplyFilter(control.lastSearchText);
|
control.ApplyFilter(control.lastSearchText);
|
||||||
control.TryExpandToSelectedItem();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,8 +81,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
{
|
{
|
||||||
if (d is HierarchicalSelectionControl control)
|
if (d is HierarchicalSelectionControl control)
|
||||||
{
|
{
|
||||||
control.LogSelectedItemChange(e.NewValue as HierarchicalSelectionItem);
|
|
||||||
control.TryExpandToSelectedItem();
|
control.TryExpandToSelectedItem();
|
||||||
|
control.SyncTreeSelectionWithSelectedItem(bringIntoView: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +106,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region UI Event Handling
|
||||||
|
|
||||||
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
|
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
EnsureTemplateParts();
|
EnsureTemplateParts();
|
||||||
@@ -116,7 +115,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
searchTextBox?.SelectAll();
|
searchTextBox?.SelectAll();
|
||||||
suppressTreeSelectionChanged = false;
|
suppressTreeSelectionChanged = false;
|
||||||
SyncTreeSelectionWithSelectedItem(bringIntoView: true);
|
SyncTreeSelectionWithSelectedItem(bringIntoView: true);
|
||||||
LogEntry($"[CategoryPicker] DropDownOpened. Selected={SelectedItem?.FullPath ?? "<null>"}");
|
|
||||||
DropDownOpened?.Invoke(this, e);
|
DropDownOpened?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +122,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
{
|
{
|
||||||
searchDelayTimer.Stop();
|
searchDelayTimer.Stop();
|
||||||
suppressTreeSelectionChanged = false;
|
suppressTreeSelectionChanged = false;
|
||||||
LogEntry("[CategoryPicker] DropDownClosed");
|
|
||||||
DropDownClosed?.Invoke(this, e);
|
DropDownClosed?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +135,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
{
|
{
|
||||||
searchDelayTimer.Stop();
|
searchDelayTimer.Stop();
|
||||||
lastSearchText = searchTextBox?.Text ?? string.Empty;
|
lastSearchText = searchTextBox?.Text ?? string.Empty;
|
||||||
LogEntry($"[CategoryPicker] Search text changed: '{lastSearchText}'");
|
|
||||||
ApplyFilter(lastSearchText);
|
ApplyFilter(lastSearchText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +149,6 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
if (original != null && !Equals(SelectedItem, original))
|
if (original != null && !Equals(SelectedItem, original))
|
||||||
{
|
{
|
||||||
SelectedItem = original;
|
SelectedItem = original;
|
||||||
LogEntry($"[CategoryPicker] Tree selection changed: {original.FullPath}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suppressTreeSelectionChanged = true;
|
suppressTreeSelectionChanged = true;
|
||||||
@@ -161,6 +156,10 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Data Preparation and Filtering
|
||||||
|
|
||||||
private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item)
|
private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
@@ -243,6 +242,10 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Tree Selection Sync
|
||||||
|
|
||||||
private void SyncTreeSelectionWithSelectedItem(bool bringIntoView)
|
private void SyncTreeSelectionWithSelectedItem(bool bringIntoView)
|
||||||
{
|
{
|
||||||
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
|
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
|
||||||
@@ -330,6 +333,10 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Template and Scroll Handling
|
||||||
|
|
||||||
private void EnsureTemplateParts()
|
private void EnsureTemplateParts()
|
||||||
{
|
{
|
||||||
if (treeViewControl == null)
|
if (treeViewControl == null)
|
||||||
@@ -349,15 +356,15 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
searchTextBox.TextChanged += SearchTextBox_TextChanged;
|
searchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (categoryScrollViewer == null)
|
if (itemsScrollViewer == null)
|
||||||
{
|
{
|
||||||
categoryScrollViewer = ComboBoxControl.Template.FindName("PART_CategoryScrollViewer", ComboBoxControl) as ScrollViewer;
|
itemsScrollViewer = ComboBoxControl.Template.FindName("PART_ItemsScrollViewer", ComboBoxControl) as ScrollViewer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CategoryScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
private void ItemsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
{
|
{
|
||||||
var scroller = categoryScrollViewer ?? sender as ScrollViewer;
|
var scroller = itemsScrollViewer ?? sender as ScrollViewer;
|
||||||
if (scroller == null || scroller.ScrollableHeight <= 0)
|
if (scroller == null || scroller.ScrollableHeight <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -392,23 +399,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDisplaySelection()
|
#endregion
|
||||||
{
|
|
||||||
// Display handled by template TextBlock bound to SelectedItem.FullPath.
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogSelectedItemChange(HierarchicalSelectionItem newValue)
|
#region Keyboard
|
||||||
{
|
|
||||||
var description = "<null>";
|
|
||||||
if (newValue != null)
|
|
||||||
{
|
|
||||||
var fullPath = string.IsNullOrWhiteSpace(newValue.FullPath) ? newValue.DisplayName : newValue.FullPath;
|
|
||||||
var id = string.IsNullOrWhiteSpace(newValue.Id) ? "<null>" : newValue.Id;
|
|
||||||
description = $"{fullPath} (Id={id})";
|
|
||||||
}
|
|
||||||
|
|
||||||
LogEntry($"[CategoryPicker] DependencyProperty SelectedItem updated -> {description}");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnPreviewKeyDown(KeyEventArgs e)
|
protected override void OnPreviewKeyDown(KeyEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -430,5 +423,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
|||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user