using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using Brush = System.Windows.Media.Brush; using Brushes = System.Windows.Media.Brushes; namespace Elwig.Helpers { public class ControlUtils { public enum RenewSourceDefault { None, IfOnly, First } private static void SetControlBorderBrush(Control input, Brush brush) { if (input is ComboBox cb) { var border = GetComboBoxBorder(cb); if (border != null) border.BorderBrush = brush; } else { input.BorderBrush = brush; } } public static void SetInputNotDefault(Control input) { SetControlBorderBrush(input, Brushes.Gold); } public static void SetInputChanged(Control input) { SetControlBorderBrush(input, Brushes.Orange); } public static void SetInputInvalid(Control input) { SetControlBorderBrush(input, Brushes.Red); } public static void ClearInputState(Control input) { if (input is ComboBox cb) { GetComboBoxBorder(cb)?.ClearValue(Border.BorderBrushProperty); } else { input.ClearValue(Control.BorderBrushProperty); } } private static Border? GetComboBoxBorder(ComboBox cb) { var toggleButton = cb.Template.FindName("toggleButton", cb) as ToggleButton; return toggleButton?.Template.FindName("templateRoot", toggleButton) as Border; } public static IEnumerable FindAllChildren(DependencyObject depObj) where T : DependencyObject { if (depObj == null) yield return (T)Enumerable.Empty(); foreach (var child in LogicalTreeHelper.GetChildren(depObj)) { if (child == null) { continue; } else if (child is T t) { yield return t; } if (child is DependencyObject childDepOpj) { foreach (T childOfChild in FindAllChildren(childDepOpj)) { yield return childOfChild; } } } } public static IEnumerable FindAllChildren(DependencyObject depObj, IEnumerable exempt) where T : DependencyObject { return FindAllChildren(depObj).Where(c => !exempt.Contains(c)); } public static T? FindNextSibling(Control me) where T : DependencyObject { var found = false; foreach (var child in LogicalTreeHelper.GetChildren(me.Parent)) { if (found && child is T c) { return c; } else if (child == me) { found = true; } } return null; } public static void RenewItemsSource(Selector selector, IEnumerable? source, SelectionChangedEventHandler? handler = null, RenewSourceDefault def = RenewSourceDefault.None) { if (selector.ItemsSource == source) return; var selectedId = Utils.GetEntityIdentifier(selector.SelectedItem); object? selItem = null; if (selectedId != 0 && source != null) selItem = source.Cast().FirstOrDefault(i => selectedId.Equals(Utils.GetEntityIdentifier(i))); if (source != null && selItem == null) { if ((def == RenewSourceDefault.IfOnly && source.Cast().Count() == 1) || def == RenewSourceDefault.First) { selItem = source.Cast().First(); } } if (handler != null && selItem != null) selector.SelectionChanged -= handler; selector.ItemsSource = source; if (handler != null && selItem != null) selector.SelectionChanged += handler; selector.SelectedItem = selItem; } public static void RenewItemsSource(DataGrid dataGrid, IEnumerable? source, SelectionChangedEventHandler? handler = null, RenewSourceDefault def = RenewSourceDefault.None, bool keepSort = true) { if (dataGrid.ItemsSource == source) return; var column = dataGrid.CurrentCell.Column; var sortColumns = dataGrid.Columns.Select(c => c.SortDirection).ToList(); var sort = dataGrid.Items.SortDescriptions.ToList(); var selectedId = Utils.GetEntityIdentifier(dataGrid.SelectedItem); object? selItem = null; if (selectedId != 0 && source != null) selItem = source.Cast().FirstOrDefault(i => selectedId.Equals(Utils.GetEntityIdentifier(i))); if (source != null && selItem == null) { if ((def == RenewSourceDefault.IfOnly && source.Cast().Count() == 1) || def == RenewSourceDefault.First) { selItem = source.Cast().First(); } } if (handler != null && selItem != null) dataGrid.SelectionChanged -= handler; dataGrid.ItemsSource = source; if (handler != null && selItem != null) dataGrid.SelectionChanged += handler; dataGrid.SelectedItem = selItem; if (keepSort) { for (int i = 0; i < dataGrid.Columns.Count; i++) dataGrid.Columns[i].SortDirection = sortColumns[i]; foreach (var s in sort) dataGrid.Items.SortDescriptions.Add(s); } if (dataGrid.SelectedItem != null && column != null) dataGrid.CurrentCell = new(dataGrid.SelectedItem, column); } public static void RenewItemsSource(ListBox listBox, IEnumerable? source, SelectionChangedEventHandler? handler = null, RenewSourceDefault def = RenewSourceDefault.None) { if (listBox.ItemsSource == source) return; var selectedId = Utils.GetEntityIdentifier(listBox.SelectedItem); object? selItem = null; if (selectedId != 0 && source != null) selItem = source.Cast().FirstOrDefault(i => selectedId.Equals(Utils.GetEntityIdentifier(i))); if (source != null && selItem == null) { if ((def == RenewSourceDefault.IfOnly && source.Cast().Count() == 1) || def == RenewSourceDefault.First) { selItem = source.Cast().FirstOrDefault(); } } if (handler != null && selItem != null) listBox.SelectionChanged -= handler; listBox.ItemsSource = source; if (handler != null && selItem != null) listBox.SelectionChanged += handler; listBox.SelectedItem = selItem; } public static object? GetItemFromSource(IEnumerable source, int? hash) { if (source == null) return null; var items = source.Cast(); var item = items.Where(i => Utils.GetEntityIdentifier(i) == hash).FirstOrDefault(); if (item == null && items.Any(i => i is NullItem)) return items.Where(i => i is NullItem).First(); return item; } public static object? GetItemFromSource(IEnumerable source, object? item) { return GetItemFromSource(source, Utils.GetEntityIdentifier(item)); } public static void SelectItemWithHash(Selector input, int? hash) { if (hash == null) { input.SelectedItem = null; } else { input.SelectedItem = GetItemFromSource(input.ItemsSource, (int)hash); } if (input is ListBox lb && lb.SelectedItem is object lbItem) { lb.ScrollIntoView(lbItem); } else if (input is DataGrid dg && dg.SelectedItem is object dgItem) { dg.ScrollIntoView(dgItem); } } public static void SelectItemWithPk(Selector input, params object?[] pk) { SelectItemWithHash(input, Utils.GetEntityIdentifier(pk)); } public static void SelectItem(Selector input, object? item) { SelectItemWithHash(input, Utils.GetEntityIdentifier(item)); } public static IEnumerable GetItemsFromSource(IEnumerable source, IEnumerable ids) { if (source == null) return []; return source.Cast().Where(i => ids.Any(c => c == Utils.GetEntityIdentifier(i))); } public static IEnumerable GetItemsFromSource(IEnumerable source, IEnumerable? items) { if (items == null) return []; return GetItemsFromSource(source, items.Select(Utils.GetEntityIdentifier)); } public static void SelectItems(ListBox lb, IEnumerable? ids) { lb.SelectedItems.Clear(); if (ids == null) return; foreach (var id in ids) lb.SelectedItems.Add(GetItemFromSource(lb.ItemsSource, id)); } public static void SelectItems(ListBox lb, IEnumerable? items) { SelectItems(lb, items?.Select(Utils.GetEntityIdentifier)); } public static int? GetInputHashCode(Control input) { if (input is TextBox tb) { return Utils.GetEntityIdentifier(tb.Text); } else if (input is ComboBox sb) { return Utils.GetEntityIdentifier(sb.SelectedItem); } else if (input is ListBox lb) { return Utils.GetEntityIdentifier(lb.SelectedItems); } else if (input is CheckBox cb) { return Utils.GetEntityIdentifier(cb.IsChecked); } else if (input is RadioButton rb) { return Utils.GetEntityIdentifier(rb.IsChecked); } else { return null; } } } }