generic hierarchical control

This commit is contained in:
Meik
2026-02-09 21:07:39 +01:00
parent e8584c1453
commit 764a8cffb8
2 changed files with 27 additions and 32 deletions

View File

@@ -105,12 +105,12 @@
Padding="4"
BorderBrush="{DynamicResource BackgroundColor.Menu.SubCategory.Hover}"
BorderThickness="1">
<ScrollViewer x:Name="PART_CategoryScrollViewer"
<ScrollViewer x:Name="PART_ItemsScrollViewer"
MaxHeight="320"
VerticalScrollBarVisibility="Auto"
Background="Transparent"
BorderThickness="0"
PreviewMouseWheel="CategoryScrollViewer_PreviewMouseWheel">
PreviewMouseWheel="ItemsScrollViewer_PreviewMouseWheel">
<TreeView x:Name="PART_TreeView"
Background="Transparent"
BorderThickness="0"

View File

@@ -8,7 +8,6 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.UserControls
{
@@ -22,7 +21,7 @@ namespace FasdDesktopUi.Basics.UserControls
private TextBox searchTextBox;
private TreeView treeViewControl;
private ScrollViewer categoryScrollViewer;
private ScrollViewer itemsScrollViewer;
public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems;
@@ -41,7 +40,6 @@ namespace FasdDesktopUi.Basics.UserControls
EnsureTemplateParts();
if (treeViewControl != null)
treeViewControl.ItemsSource = VisibleItems;
UpdateDisplaySelection();
}
#region DependencyProperties
@@ -64,7 +62,6 @@ namespace FasdDesktopUi.Basics.UserControls
{
control.RebuildLookup();
control.ApplyFilter(control.lastSearchText);
control.TryExpandToSelectedItem();
}
}
@@ -84,8 +81,8 @@ namespace FasdDesktopUi.Basics.UserControls
{
if (d is HierarchicalSelectionControl control)
{
control.LogSelectedItemChange(e.NewValue as HierarchicalSelectionItem);
control.TryExpandToSelectedItem();
control.SyncTreeSelectionWithSelectedItem(bringIntoView: false);
}
}
@@ -109,6 +106,8 @@ namespace FasdDesktopUi.Basics.UserControls
#endregion
#region UI Event Handling
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
{
EnsureTemplateParts();
@@ -116,7 +115,6 @@ namespace FasdDesktopUi.Basics.UserControls
searchTextBox?.SelectAll();
suppressTreeSelectionChanged = false;
SyncTreeSelectionWithSelectedItem(bringIntoView: true);
LogEntry($"[CategoryPicker] DropDownOpened. Selected={SelectedItem?.FullPath ?? "<null>"}");
DropDownOpened?.Invoke(this, e);
}
@@ -124,7 +122,6 @@ namespace FasdDesktopUi.Basics.UserControls
{
searchDelayTimer.Stop();
suppressTreeSelectionChanged = false;
LogEntry("[CategoryPicker] DropDownClosed");
DropDownClosed?.Invoke(this, e);
}
@@ -138,7 +135,6 @@ namespace FasdDesktopUi.Basics.UserControls
{
searchDelayTimer.Stop();
lastSearchText = searchTextBox?.Text ?? string.Empty;
LogEntry($"[CategoryPicker] Search text changed: '{lastSearchText}'");
ApplyFilter(lastSearchText);
}
@@ -153,7 +149,6 @@ namespace FasdDesktopUi.Basics.UserControls
if (original != null && !Equals(SelectedItem, original))
{
SelectedItem = original;
LogEntry($"[CategoryPicker] Tree selection changed: {original.FullPath}");
}
suppressTreeSelectionChanged = true;
@@ -161,6 +156,10 @@ namespace FasdDesktopUi.Basics.UserControls
}
}
#endregion
#region Data Preparation and Filtering
private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item)
{
if (item == null)
@@ -243,6 +242,10 @@ namespace FasdDesktopUi.Basics.UserControls
}
}
#endregion
#region Tree Selection Sync
private void SyncTreeSelectionWithSelectedItem(bool bringIntoView)
{
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
@@ -330,6 +333,10 @@ namespace FasdDesktopUi.Basics.UserControls
return null;
}
#endregion
#region Template and Scroll Handling
private void EnsureTemplateParts()
{
if (treeViewControl == null)
@@ -349,15 +356,15 @@ namespace FasdDesktopUi.Basics.UserControls
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)
return;
@@ -392,23 +399,9 @@ namespace FasdDesktopUi.Basics.UserControls
e.Handled = true;
}
private void UpdateDisplaySelection()
{
// Display handled by template TextBlock bound to SelectedItem.FullPath.
}
#endregion
private void LogSelectedItemChange(HierarchicalSelectionItem newValue)
{
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}");
}
#region Keyboard
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
@@ -430,5 +423,7 @@ namespace FasdDesktopUi.Basics.UserControls
e.Handled = true;
}
}
#endregion
}
}