JD2022-TU1/main/tools/modules/JD.Guinness.WPF.Module/ItemFocuser.cs

70 lines
2.2 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using ActiproSoftware.Windows.Controls.Docking;
namespace JD.Guinness.WPF.Module
{
public sealed class ItemFocuser
{
private event Action<object> GoToItemAsked;
public DelegateCommand<object> GoToItemCommand { get; }
public ItemFocuser()
{
GoToItemCommand = new DelegateCommand<object>(OnGoToItem, i => i != null);
}
private void OnGoToItem(object item) => GoToItemAsked?.Invoke(item);
private void TryShowWindow(FrameworkElement element)
{
while (element != null)
{
element = element.Parent as FrameworkElement;
if (element is ToolWindow window)
{
window.Activate(true);
// wait for ui display
element.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null);
break;
}
}
}
private void TryGoTo<T>(DataGrid dataGrid, object item)
{
if (item is T t)
{
TryShowWindow(dataGrid);
dataGrid.ScrollIntoView(t);
if (dataGrid.ItemContainerGenerator.ContainerFromItem(t) is DataGridRow row)
{
dataGrid.SelectedItem = t;
// simulate keyboard focus so the element is properly selected
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
}
}
private void TryGoTo<T>(TabControl tabControl, object item)
{
if (item is T t)
{
TryShowWindow(tabControl);
tabControl.SelectedItem = item;
}
}
public void Subscribe<T>(DataGrid dataGrid) => GoToItemAsked += i => TryGoTo<T>(dataGrid, i);
public void Subscribe<T>(TabControl tabControl) => GoToItemAsked += i => TryGoTo<T>(tabControl, i);
public void SubscribeWindow<T>(FrameworkElement element) => GoToItemAsked += i => { if (i is T) TryShowWindow(element); };
}
}