using System; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using InABox.Clients; using InABox.Configuration; using InABox.Core; using InABox.Wpf; using Syncfusion.Data; using Button = System.Windows.Controls.Button; namespace InABox.DynamicGrid { public interface IMultiSelectDialog { bool ShowDialog(String? column = null, String? filter = null, FilterType filtertype = FilterType.Contains); Guid[] IDs(); CoreTable Data(); Entity[] Items(IColumns? columns = null); } public class MultiSelectDialogSettings : BaseObject, IUserConfigurationSettings { public DynamicGridSelectedFilterSettings Filters { get; set; } = new(); } public class MultiSelectDialog : IMultiSelectDialog where T : Entity, IRemotable, IPersistent, new() { //private Expression>[] _columns = new Expression>[] { }; private readonly Columns? _columns; private readonly Filter? _filter; private readonly DynamicDataGrid datagrid; private readonly Grid grid; private readonly Button ClearButton; private readonly Button OKButton; private ThemableWindow? window; public MultiSelectDialog() : this(null, null) { } //public MultiSelectDialog(Filter filter, Expression>[] columns, bool multiselect = true) : base() public MultiSelectDialog(Filter? filter, Columns? columns, bool multiselect = true) { _filter = filter; grid = new Grid(); grid.Margin = new Thickness(5); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) }); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(40.0F, GridUnitType.Pixel) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(80.0F, GridUnitType.Pixel) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(80.0F, GridUnitType.Pixel) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(80.0F, GridUnitType.Pixel) }); datagrid = new DynamicDataGrid(); datagrid.Reconfigure(options => { options.BeginUpdate(); options.Clear(); options.SelectColumns = true; options.FilterRows = true; if (multiselect) options.MultiSelect = true; options.EndUpdate(); }); datagrid.Reconfigure(); datagrid.OnReload += Grid_OnReload; datagrid.OnDoubleClick += Grid_DoubleClick; datagrid.ColumnsTag = "MSD"; if (columns != null) { _columns = columns; foreach (var column in columns) datagrid.AddHiddenColumn(column.Property); //datagrid.HiddenColumns.AddRange(columns); } else { var cols = LookupFactory.DefineColumns() .AddColumns(ColumnTypeFlags.IncludeOptional | ColumnTypeFlags.IncludeForeignKeys | ColumnTypeFlags.IncludeLinked); foreach (var col in cols) datagrid.AddHiddenColumn(col.ToString()); } var _settings = new UserConfiguration(datagrid.GetTag()).Load(); datagrid.FilterComponent.SetSettings(_settings.Filters,false); datagrid.FilterComponent.OnFiltersSelected += (settings) => { var _settings = new MultiSelectDialogSettings() { Filters = settings }; new UserConfiguration(datagrid.GetTag()).Save(_settings); }; datagrid.SetValue(Grid.RowProperty, 0); datagrid.SetValue(Grid.ColumnProperty, 0); datagrid.SetValue(Grid.ColumnSpanProperty, 4); datagrid.OnSelectItem += Datagrid_OnSelectItem; grid.Children.Add(datagrid); ClearButton = new Button(); ClearButton.Margin = new Thickness(0, 5, 5, 0); ClearButton.Content = "Clear"; ClearButton.Click += ClearButton_Click; ClearButton.SetValue(Grid.RowProperty, 1); ClearButton.SetValue(Grid.ColumnProperty, 0); grid.Children.Add(ClearButton); OKButton = new Button(); OKButton.Margin = new Thickness(5, 5, 0, 0); OKButton.Content = "OK"; OKButton.Click += OKButton_Click; OKButton.SetValue(Grid.RowProperty, 1); OKButton.SetValue(Grid.ColumnProperty, 2); OKButton.IsEnabled = false; grid.Children.Add(OKButton); var CancelButton = new Button(); CancelButton.Margin = new Thickness(5, 5, 0, 0); CancelButton.Content = "Cancel"; CancelButton.Click += CancelButton_Click; CancelButton.SetValue(Grid.RowProperty, 1); CancelButton.SetValue(Grid.ColumnProperty, 3); grid.Children.Add(CancelButton); } public bool ShowDialog(string? column = null, string? value = null, FilterType filtertype = FilterType.Contains) => ShowDialogInternal(null, column, value, filtertype); public bool ShowDialog(string title) => ShowDialogInternal(title, null, null, default); private bool ShowDialogInternal(string? title, string? column, string? value, FilterType filtertype) { window = new ThemableWindow { Title = title ?? "Select Items", WindowStyle = WindowStyle.SingleBorderWindow, Content = grid }; datagrid.Refresh(true, true); if (!column.IsNullOrWhiteSpace() && !value.IsNullOrWhiteSpace()) datagrid.AddVisualFilter(column, value, filtertype); if (window.ShowDialog() == true) return true; return false; } private Window GetWindow([CallerMemberName] string methodName = "") { return window ?? throw new Exception($"Must call ShowDialog() before {methodName}()"); } public Guid[] IDs() { var window = GetWindow(); if (window.DialogResult == true) { if (datagrid?.Data != null && datagrid.SelectedRows.Any()) return datagrid.SelectedRows.Select(r => r.Get(x => x.ID)).ToArray(); } else if (window.DialogResult == false) return new Guid[] { Guid.Empty }; return Array.Empty(); } public CoreTable Data() { var window = GetWindow(); var result = new CoreTable(); result.Columns.Add(new CoreColumn { ColumnName = "ID", DataType = typeof(Guid) }); if(_columns is not null) { foreach (var column in _columns.Where(x => !string.Equals(x.Property, "ID"))) result.Columns.Add(new CoreColumn { ColumnName = column.Property, DataType = column.Type }); } if (window.DialogResult == true) { if (datagrid?.Data != null && datagrid.SelectedRows.Any()) foreach (var sel in datagrid.SelectedRows) { var row = result.NewRow(); foreach (var column in result.Columns) { var value = sel[column.ColumnName]; row.Set(column.ColumnName, value); } result.Rows.Add(row); } } else if (window.DialogResult == false) { var row = result.NewRow(true); result.Rows.Add(row); } return result; } public T[] Items(Columns? columns = null) { var window = GetWindow(); if (window.DialogResult == true) { if (datagrid.Data != null && datagrid.SelectedRows.Any()) { Filter? flt = null; foreach (var row in datagrid.SelectedRows) { var id = row.Get(x => x.ID); flt = flt == null ? new Filter(x => x.ID).IsEqualTo(id) : flt.Or(x => x.ID).IsEqualTo(id); } var items = new Client().Query(flt, columns).Rows.Select(r => r.ToObject()); return items.ToArray(); } } else if (window.DialogResult == false) return new T[] { new T() }; return Array.Empty(); } Entity[] IMultiSelectDialog.Items(IColumns? columns) => Items(columns as Columns); private void Grid_DoubleClick(object sender, HandledEventArgs args) { args.Handled = true; window!.DialogResult = true; window.Close(); } private void Datagrid_OnSelectItem(object sender, DynamicGridSelectionEventArgs e) { OKButton.IsEnabled = e.Rows?.Any() == true; } private void CancelButton_Click(object sender, RoutedEventArgs e) { window!.Close(); } private void OKButton_Click(object sender, RoutedEventArgs e) { window!.DialogResult = true; window.Close(); } private void ClearButton_Click(object sender, RoutedEventArgs e) { window!.DialogResult = false; window.Close(); } private void Grid_OnReload(object sender, Filters criteria, Columns columns, ref SortOrder? sortby) { if (_filter != null) criteria.Add(_filter); } } }