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 GoToItemAsked; public DelegateCommand GoToItemCommand { get; } public ItemFocuser() { GoToItemCommand = new DelegateCommand(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(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(TabControl tabControl, object item) { if (item is T t) { TryShowWindow(tabControl); tabControl.SelectedItem = item; } } public void Subscribe(DataGrid dataGrid) => GoToItemAsked += i => TryGoTo(dataGrid, i); public void Subscribe(TabControl tabControl) => GoToItemAsked += i => TryGoTo(tabControl, i); public void SubscribeWindow(FrameworkElement element) => GoToItemAsked += i => { if (i is T) TryShowWindow(element); }; } }