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 List _items; public string SearchText { get; set; } public DynamicGridColumnNameSelectorGrid(Type type, string[] columnNames) { var items = new List(); var parentCols = new HashSet(); foreach (var column in columnNames) { 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.Add(parent); } var item = new DynamicGridColumnNameSelectorItem { ColumnName = column, ParentColumn = parent, Display = props[^1], IsParent = false, Comment = DatabaseSchema.Property(type, column)?.Comment ?? "" }; items.Add(item); } foreach (var col in parentCols) { var lastColIdx = col.LastIndexOf('.'); var item = new DynamicGridColumnNameSelectorItem { ColumnName = col, IsParent = true, Comment = DatabaseSchema.Property(type, col)?.Comment ?? "" }; 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; } 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); } } } base.Reload(criteria, columns, ref sort, token, action); } public static bool SelectColumnName(Type type, string[] columnNames, out string value) { var grid = new DynamicGridColumnNameSelectorGrid(type, columnNames) { }; 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 control = new Grid(); control.AddColumn(GridUnitType.Auto); control.AddColumn(GridUnitType.Star); control.AddRow(GridUnitType.Auto); control.AddRow(GridUnitType.Star); control.AddChild(lbl, 0, 0); control.AddChild(search, 0, 1); control.AddChild(grid, 1, 0, colSpan: 2); 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 IsParent { get; set; } }