using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
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);
bool CanAdd { get; set; }
}
public class MultiSelectDialogSettings : BaseObject, IUserConfigurationSettings
{
public DynamicGridSelectedFilterSettings Filters { get; set; } = new();
}
///
/// Represents a dialog to select (s), given a filter and a set of columns. It can either do multi-selecting or single-selecting.
///
///
/// This is the standard way to do a selection dialog. To access all selected IDs, use ; to access the data according to the columns
/// provided in the constructor, use ; use if you want to load all the items with the selected IDs with a custom
/// set of columns.
///
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 CancelButton;
private readonly Button OKButton;
private ThemableWindow? window;
public bool CanAdd { get; set; } = true;
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.Margin = new Thickness(5);
datagrid.Reconfigure(options =>
{
options.BeginUpdate();
options.Clear();
options.SelectColumns = true;
options.FilterRows = true;
if (multiselect)
options.MultiSelect = true;
options.AddRows = CanAdd;
options.RecordCount = true;
options.EndUpdate();
});
datagrid.Reconfigure();
OKButton = datagrid.AddButton("OK", null, OKClick, DynamicGridButtonPosition.Right);
OKButton.Width = 80;
OKButton.IsEnabled = false;
CancelButton = datagrid.AddButton("Cancel", null, CancelClick, DynamicGridButtonPosition.Right);
CancelButton.Width = 80;
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);
}
private bool OKClick(Button button, CoreRow[] rows)
{
window!.DialogResult = true;
window!.Close();
return false;
}
private bool CancelClick(Button button, CoreRow[] rows)
{
window!.DialogResult = false;
window!.Close();
return false;
}
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 = datagrid
};
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)
{
return datagrid.SelectedRows.ToArray(r => r.Get(x => x.ID));
}
else if (window.DialogResult == false)
{
return [Guid.Empty];
}
else
{
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.Length != 0)
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)
{
var ids = datagrid.SelectedRows.ToArray(r => r.Get(x => x.ID));
if (ids.Length > 0)
{
return new Client().Query(new Filter(x => x.ID).InList(ids), columns).ToArray();
}
}
else if (window.DialogResult == false)
return [new T()];
return [];
}
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!.DialogResult = false;
// 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);
}
public static bool SelectItem([NotNullWhen(true)] out T? item, Filter? filter = null, Columns? columns = null, string? title = null)
{
var dlg = new MultiSelectDialog(filter, columns, multiselect: false);
if (dlg.ShowDialogInternal(title, null, null, default))
{
item = dlg.Data().ToObjects().FirstOrDefault();
return item is not null;
}
else
{
item = null;
return false;
}
}
public static bool SelectItems([NotNullWhen(true)] out T[]? items, Filter? filter = null, Columns? columns = null, string? title = null)
{
var dlg = new MultiSelectDialog(filter, columns, multiselect: true);
if (dlg.ShowDialogInternal(title, null, null, default))
{
items = dlg.Data().ToArray();
return true;
}
else
{
items = null;
return false;
}
}
}
public static class MultiSelectDialog
{
public static bool SelectItem([NotNullWhen(true)] out T? item, Filter? filter = null, Columns? columns = null, string? title = null)
where T : Entity, IRemotable, IPersistent, new()
{
return MultiSelectDialog.SelectItem(out item, filter: filter, columns: columns, title: title);
}
public static bool SelectItems([NotNullWhen(true)] out T[]? items, Filter? filter = null, Columns? columns = null, string? title = null)
where T : Entity, IRemotable, IPersistent, new()
{
return MultiSelectDialog.SelectItems(out items, filter: filter, columns: columns, title: title);
}
}