using InABox.Core; using InABox.WPF; using Syncfusion.Pdf.Parsing; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace InABox.DynamicGrid; public class DynamicGridColumnNameSelectorGrid : DynamicItemsListGrid, INotifyPropertyChanged { private bool _canSave; public bool CanSave { get => _canSave; set { _canSave = value; DoPropertyChanged(); } } private bool _onlyVisible; public bool OnlyVisible { get => _onlyVisible; set { _onlyVisible = value; Refresh(false, true); DoPropertyChanged(); } } private List _items; public string SearchText { get; set; } = ""; public DynamicGridColumnNameSelectorGrid(IDynamicGridColumnSchema schema) { var itemMap = new Dictionary(); var items = new List(); var parentCols = new Dictionary>(); foreach (var column in schema.ColumnNames) { var item = new DynamicGridColumnNameSelectorItem(); var props = column.Split('.'); string? parent = null; for (int i = 0; i < props.Length - 1; ++i) { if (parent is null) { parent = props[i]; } else { parent = $"{parent}.{props[i]}"; } parentCols.GetValueOrAdd(parent).Add(item); } item.ColumnName = column; item.ParentColumn = parent; item.Display = props[^1]; item.IsParent = false; item.Comment = schema.GetComment(column) ?? ""; item.IsVisible = schema.IsVisible(column); items.Add(item); } foreach (var (col, children) in parentCols) { var lastColIdx = col.LastIndexOf('.'); var item = new DynamicGridColumnNameSelectorItem { ColumnName = col, IsParent = true, Comment = schema.GetComment(col) ?? "", IsVisible = children.Any(x => x.IsVisible) }; if (lastColIdx == -1) { item.ParentColumn = null; item.Display = col; } else { item.ParentColumn = col[..lastColIdx]; item.Display = col[(lastColIdx + 1)..]; } items.Add(item); } items.Sort((a, b) => a.ColumnName.CompareTo(b.ColumnName)); _items = items; } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.Clear(); options.FilterRows = true; } protected override void SelectItems(CoreRow[]? rows) { base.SelectItems(rows); CanSave = rows is not null && rows.Any(x => !LoadItem(x).IsParent); if(rows is not null) { foreach(var row in rows) { Component.ExpandRow(row); } } } protected override DynamicGridColumns LoadColumns() { var columns = new DynamicGridColumns(); columns.Add(x => x.Display, caption: "Name", width: 250); columns.Add(x => x.Comment); return columns; } private UIComponent? _uiComponent; private UIComponent Component { get { _uiComponent ??= new UIComponent(this); return _uiComponent; } } private class UIComponent : DynamicGridTreeUIComponent { DynamicGridColumnNameSelectorGrid Grid; public UIComponent(DynamicGridColumnNameSelectorGrid grid) : base(x => x.ColumnName, x => x.ParentColumn, null) { Parent = grid; Grid = grid; ExpandMode = DynamicTreeGridExpandMode.None; ShowHeader = false; MinRowHeight = 25; GridLines = DynamicTreeGridLines.Horizontal; } protected override Brush? GetCellForeground(CoreRow row, DynamicColumnBase column) { if(column is DynamicGridColumn gc && gc.ColumnName == nameof(DynamicGridColumnNameSelectorItem.Comment)) { return Colors.Gray.ToBrush(); } else { var item = Grid.LoadItem(row); if (item.IsParent) { return Colors.Gray.ToBrush(); } else { return base.GetCellForeground(row, column); } } } protected override FontStyle? GetCellFontStyle(CoreRow row, DynamicColumnBase column) { if(column is DynamicGridColumn gc && gc.ColumnName == nameof(DynamicGridColumnNameSelectorItem.Comment)) { return FontStyles.Italic; } else { var item = Grid.LoadItem(row); if (item.IsParent) { return FontStyles.Italic; } else { return base.GetCellFontStyle(row, column); } } } } protected override IDynamicGridUIComponent CreateUIComponent() => Component; public event PropertyChangedEventHandler? PropertyChanged; protected void DoPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new(propertyName)); } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, CancellationToken token, Action action) { if (SearchText.IsNullOrWhiteSpace()) { Items = _items.ToList(); } else { Items = new(); foreach(var item in _items) { if (!item.IsParent && item.ColumnName.Contains(SearchText, StringComparison.CurrentCultureIgnoreCase)) { Items.Add(item); } } foreach(var item in _items) { if (item.IsParent && Items.Any(x => x.ColumnName.StartsWith(item.ColumnName + "."))) { Items.Add(item); } } } if (OnlyVisible) { Items.RemoveAll(x => !x.IsVisible); } base.Reload(criteria, columns, ref sort, token, action); } public static bool SelectColumnName(Type type, IEnumerable columnNames, out string value, bool showVisibilityButton = false) { return SelectColumnName(new DynamicGridObjectColumnSchema(type, columnNames), out value, showVisibilityButton: showVisibilityButton); } public static bool SelectColumnName(IDynamicGridColumnSchema schema, out string value, bool showVisibilityButton = false) { var grid = new DynamicGridColumnNameSelectorGrid(schema) { OnlyVisible = showVisibilityButton }; grid.Refresh(true, true); var lbl = new Label { Content = "Search:", Margin = new Thickness(0, 0, 5, 5) }; var search = new TextBox { Background = Colors.LightYellow.ToBrush(), Height = 25, Margin = new Thickness(0, 0, 0, 5), VerticalContentAlignment = VerticalAlignment.Center, }; search.TextChanged += (o, e) => { grid.SearchText = search.Text; grid.Refresh(false, true); }; var onlyVisible = new CheckBox() { Content = "Only Visible?", VerticalAlignment = VerticalAlignment.Center, Margin = new(5, 0, 0, 5) }; onlyVisible.Bind(CheckBox.IsCheckedProperty, grid, x => x.OnlyVisible); var control = new Grid(); control.AddColumn(GridUnitType.Auto); control.AddColumn(GridUnitType.Star); if (showVisibilityButton) { control.AddColumn(GridUnitType.Auto); } else { control.AddColumn(0); } control.AddRow(GridUnitType.Auto); control.AddRow(GridUnitType.Star); control.AddChild(lbl, 0, 0); control.AddChild(search, 0, 1); control.AddChild(onlyVisible, 0, 2); control.AddChild(grid, 1, 0, colSpan: 3); var window = new DynamicContentDialog(control) { Title = "Select Column", Width = 600, Height = 600, WindowStartupLocation = WindowStartupLocation.CenterScreen }; window.Bind(DynamicContentDialog.CanSaveProperty, grid, x => x.CanSave); grid.OnCellDoubleClick += (o, e) => { if (e.Row is null) return; var item = grid.LoadItem(e.Row); if (!item.IsParent) { window.DialogResult = true; } }; if(window.ShowDialog() == true && grid.SelectedRows.FirstOrDefault() is CoreRow row) { var item = grid.LoadItem(row); if (!item.IsParent) { value = item.ColumnName; return true; } } value = ""; return false; } } public class DynamicGridColumnNameSelectorItem : BaseObject { public string ColumnName { get; set; } = ""; public string Display { get; set; } = ""; public string? ParentColumn { get; set; } public string Comment { get; set; } = ""; public bool IsVisible { get; set; } public bool IsParent { get; set; } }