|
@@ -12,7 +12,6 @@ using InABox.Clients;
|
|
|
using InABox.Configuration;
|
|
|
using InABox.Core;
|
|
|
using InABox.WPF;
|
|
|
-using Syncfusion.XlsIO;
|
|
|
using Expression = System.Linq.Expressions.Expression;
|
|
|
|
|
|
namespace InABox.DynamicGrid
|
|
@@ -30,6 +29,10 @@ namespace InABox.DynamicGrid
|
|
|
|
|
|
public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
{
|
|
|
+ public delegate bool FilterSelected(DynamicGridFilter filter);
|
|
|
+
|
|
|
+ public event FilterSelected OnFilterSelected;
|
|
|
+
|
|
|
public delegate void OnReloadEventHandler(object sender, Filters<TEntity> criteria, Columns<TEntity> columns, ref SortOrder<TEntity>? sortby);
|
|
|
|
|
|
private readonly int ChunkSize = 500;
|
|
@@ -37,12 +40,13 @@ namespace InABox.DynamicGrid
|
|
|
private readonly Button FilterBtn;
|
|
|
|
|
|
private bool _showFilterList;
|
|
|
- public bool ShowFilterList {
|
|
|
+ public bool ShowFilterList
|
|
|
+ {
|
|
|
get => _showFilterList;
|
|
|
set
|
|
|
{
|
|
|
_showFilterList = value;
|
|
|
- if(FilterBtn != null) // FilterBtn can be null when ShowFilterList is set in DynamicGrid constructor
|
|
|
+ if (FilterBtn != null) // FilterBtn can be null when ShowFilterList is set in DynamicGrid constructor
|
|
|
FilterBtn.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
|
|
|
}
|
|
|
}
|
|
@@ -53,7 +57,7 @@ namespace InABox.DynamicGrid
|
|
|
|
|
|
public DynamicDataGrid() : base()
|
|
|
{
|
|
|
- FilterBtn = AddButton("",Wpf.Resources.filter.AsBitmapImage(), DoFilter);
|
|
|
+ FilterBtn = AddButton("", Wpf.Resources.filter.AsBitmapImage(), DoFilter);
|
|
|
FilterBtn.Margin = new Thickness(0, 2, 7, 0);
|
|
|
FilterBtn.Padding = new Thickness(0);
|
|
|
FilterBtn.Visibility = ShowFilterList ? Visibility.Visible : Visibility.Collapsed;
|
|
@@ -71,20 +75,20 @@ namespace InABox.DynamicGrid
|
|
|
Options.Add(DynamicGridOption.MultiSelect);
|
|
|
Options.EndUpdate();
|
|
|
|
|
|
- MergeBtn = AddButton("Merge",Wpf.Resources.merge.AsBitmapImage(Color.White), DoMerge);
|
|
|
+ MergeBtn = AddButton("Merge", Wpf.Resources.merge.AsBitmapImage(Color.White), DoMerge);
|
|
|
|
|
|
var fields = DatabaseSchema.Properties(typeof(TEntity));
|
|
|
-
|
|
|
+
|
|
|
foreach (var field in fields)
|
|
|
if (!MasterColumns.Any(x => x.ColumnName == field.Name))
|
|
|
MasterColumns.Add(new DynamicGridColumn { ColumnName = field.Name });
|
|
|
-
|
|
|
+
|
|
|
var cols = LookupFactory.DefineColumns<TEntity>();
|
|
|
-
|
|
|
+
|
|
|
// Minimum Columns for Lookup values
|
|
|
foreach (var col in cols.Items)
|
|
|
HiddenColumns.Add(CoreUtils.CreateLambdaExpression<TEntity>(col.Property));
|
|
|
-
|
|
|
+
|
|
|
// Minimum Columns for Successful Saving
|
|
|
// This should be cross-checked with the relevant Store<>
|
|
|
// so that clients will (usually) provide sufficient columns for saving
|
|
@@ -124,7 +128,7 @@ namespace InABox.DynamicGrid
|
|
|
FilterColumns = new[] { new Column<TEntity>(x => x.ID) };
|
|
|
}
|
|
|
|
|
|
- foreach(var column in FilterColumns)
|
|
|
+ foreach (var column in FilterColumns)
|
|
|
{
|
|
|
AddHiddenColumn(column.Property);
|
|
|
}
|
|
@@ -132,7 +136,7 @@ namespace InABox.DynamicGrid
|
|
|
|
|
|
protected override void BeforeLoad(IDynamicEditorForm form)
|
|
|
{
|
|
|
- form.ReadOnly = !Security.CanEdit<TEntity>();
|
|
|
+ form.ReadOnly = !Security.CanEdit<TEntity>();
|
|
|
base.BeforeLoad(form);
|
|
|
}
|
|
|
|
|
@@ -221,7 +225,7 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
base.OnAfterRefresh();
|
|
|
|
|
|
- if(SelectedBeforeRefresh is not null)
|
|
|
+ if (SelectedBeforeRefresh is not null)
|
|
|
{
|
|
|
var selectedValues = SelectedBeforeRefresh
|
|
|
.Select(x => FilterColumns.Select(c => x[c.Property]).ToList())
|
|
@@ -233,7 +237,7 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
return selectedValues.Any(v =>
|
|
|
{
|
|
|
- for(int i = 0; i < v.Count; ++i)
|
|
|
+ for (int i = 0; i < v.Count; ++i)
|
|
|
{
|
|
|
if (v[i]?.Equals(r[FilterColumns[i].Property]) != true)
|
|
|
return false;
|
|
@@ -258,8 +262,8 @@ namespace InABox.DynamicGrid
|
|
|
public Columns<TEntity> LoadEditorColumns()
|
|
|
{
|
|
|
var result = new Columns<TEntity>().Default(
|
|
|
- ColumnType.IncludeOptional,
|
|
|
- ColumnType.IncludeForeignKeys,
|
|
|
+ ColumnType.IncludeOptional,
|
|
|
+ ColumnType.IncludeForeignKeys,
|
|
|
ColumnType.IncludeUserProperties,
|
|
|
ColumnType.IncludeEditable);
|
|
|
var cols = DataColumns();
|
|
@@ -270,12 +274,12 @@ namespace InABox.DynamicGrid
|
|
|
var props = DatabaseSchema.Properties(typeof(TEntity))
|
|
|
.Where(x => x.Setter() != null)
|
|
|
.OrderBy(x => CoreUtils.GetPropertySequence(typeof(TEntity), x.Name));
|
|
|
- foreach(var col in result.Items)
|
|
|
+ foreach (var col in result.Items)
|
|
|
{
|
|
|
var prop = DatabaseSchema.Property(typeof(TEntity), col.Property);
|
|
|
- if(prop?.Editor is DataLookupEditor dataLookup)
|
|
|
+ if (prop?.Editor is DataLookupEditor dataLookup)
|
|
|
{
|
|
|
- foreach(var lookupColumn in LookupFactory.DefineFilterColumns<TEntity>(dataLookup.Type).ColumnNames())
|
|
|
+ foreach (var lookupColumn in LookupFactory.DefineFilterColumns<TEntity>(dataLookup.Type).ColumnNames())
|
|
|
{
|
|
|
result.Add(lookupColumn);
|
|
|
}
|
|
@@ -306,7 +310,7 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
var newFilter = GetRowFilter(row);
|
|
|
|
|
|
- if(newFilter is not null)
|
|
|
+ if (newFilter is not null)
|
|
|
{
|
|
|
//var id = row.Get<TEntity, Guid>(x => x.ID);
|
|
|
if (filter is null)
|
|
@@ -348,7 +352,7 @@ namespace InABox.DynamicGrid
|
|
|
foreach (var row in rows)
|
|
|
{
|
|
|
var delete = new TEntity();
|
|
|
- foreach(var column in FilterColumns)
|
|
|
+ foreach (var column in FilterColumns)
|
|
|
{
|
|
|
CoreUtils.SetPropertyValue(delete, column.Property, row[column.Property]);
|
|
|
}
|
|
@@ -397,7 +401,7 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
base.LoadEditorButtons(item, buttons);
|
|
|
if (ClientFactory.IsSupported<AuditTrail>())
|
|
|
- buttons.Add("Audit Trail",Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
|
|
|
+ buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
|
|
|
}
|
|
|
|
|
|
private void AuditTrailClick(object sender, object item)
|
|
@@ -511,7 +515,7 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
var cols = new Columns<TEntity>().Default(Options.Contains(DynamicGridOption.DirectEdit)
|
|
|
? new[] { ColumnType.IncludeForeignKeys, ColumnType.ExcludeID }
|
|
|
- : new ColumnType[] {
|
|
|
+ : new ColumnType[] {
|
|
|
ColumnType.IncludeLinked, ColumnType.IncludeNestedLinks, ColumnType.IncludeFormulae,
|
|
|
ColumnType.IncludeAggregates, ColumnType.ExcludeID });
|
|
|
if (cols != null)
|
|
@@ -541,7 +545,7 @@ namespace InABox.DynamicGrid
|
|
|
|
|
|
protected override object? GetEditorValue(object item, string name)
|
|
|
{
|
|
|
- if(item is TEntity entity)
|
|
|
+ if (item is TEntity entity)
|
|
|
{
|
|
|
var prop = DatabaseSchema.Properties(typeof(TEntity)).FirstOrDefault(x => x.Name == name);
|
|
|
if (prop is CustomProperty)
|
|
@@ -629,7 +633,7 @@ namespace InABox.DynamicGrid
|
|
|
x.PropertyType.GetInterfaces().Contains(typeof(IEntityLink)) &&
|
|
|
x.PropertyType.GetInheritedGenericTypeArguments().FirstOrDefault() == typeof(TEntity));
|
|
|
|
|
|
- if(prop is not null)
|
|
|
+ if (prop is not null)
|
|
|
{
|
|
|
var filter = Core.Filter.Create(childtype);
|
|
|
filter.Expression = CoreUtils.GetMemberExpression(childtype, prop.Name + ".ID");
|
|
@@ -707,10 +711,10 @@ namespace InABox.DynamicGrid
|
|
|
|
|
|
var tag = GetTag();
|
|
|
var filters = new GlobalConfiguration<DynamicGridFilters>(tag).Load();
|
|
|
- foreach(var filter in filters)
|
|
|
+ foreach (var filter in filters)
|
|
|
{
|
|
|
var item = new MenuItem { Header = filter.Name, Tag = filter };
|
|
|
- if(SelectedFilter?.Item1 == filter.Name)
|
|
|
+ if (SelectedFilter?.Item1 == filter.Name)
|
|
|
{
|
|
|
item.IsChecked = true;
|
|
|
}
|
|
@@ -725,7 +729,7 @@ namespace InABox.DynamicGrid
|
|
|
manage.Click += (s, e) =>
|
|
|
{
|
|
|
var window = new DynamicGridFilterEditor(filters, typeof(TEntity));
|
|
|
- if(window.ShowDialog() == true)
|
|
|
+ if (window.ShowDialog() == true)
|
|
|
{
|
|
|
new GlobalConfiguration<DynamicGridFilters>(tag).Save(filters);
|
|
|
}
|
|
@@ -741,18 +745,22 @@ namespace InABox.DynamicGrid
|
|
|
private void Filter_Click(object sender, RoutedEventArgs e)
|
|
|
{
|
|
|
var tag = (sender as MenuItem)?.Tag;
|
|
|
+ string text = "";
|
|
|
Bitmap image;
|
|
|
- if(tag is DynamicGridFilter filter)
|
|
|
+ if (tag is DynamicGridFilter filter)
|
|
|
{
|
|
|
SelectedFilter = new(filter.Name, Serialization.Deserialize<Filter<TEntity>>(filter.Filter));
|
|
|
- image =Wpf.Resources.filter_set;
|
|
|
+ image = Wpf.Resources.filter_set;
|
|
|
+ if ((bool)(OnFilterSelected?.Invoke(filter)))
|
|
|
+ text = filter.Name;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SelectedFilter = null;
|
|
|
- image =Wpf.Resources.filter;
|
|
|
+ image = Wpf.Resources.filter;
|
|
|
+ OnFilterSelected?.Invoke(new DynamicGridFilter());
|
|
|
}
|
|
|
- UpdateButton(FilterBtn, image.AsBitmapImage(), "");
|
|
|
+ UpdateButton(FilterBtn, image.AsBitmapImage(), text);
|
|
|
Refresh(false, true);
|
|
|
}
|
|
|
|
|
@@ -943,5 +951,10 @@ namespace InABox.DynamicGrid
|
|
|
{
|
|
|
return new Client<TEntity>().Query(null, new Columns<TEntity>(fields));
|
|
|
}
|
|
|
+
|
|
|
+ public void UpdateFilterButton(Bitmap image, string text = "")
|
|
|
+ {
|
|
|
+ UpdateButton(FilterBtn, image.AsBitmapImage(), text);
|
|
|
+ }
|
|
|
}
|
|
|
}
|