using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Threading;
using System.Xml;
using InABox.Clients;
using InABox.Configuration;
using InABox.Core;
using InABox.WPF;
using NPOI.SS.Formula.Functions;
namespace InABox.DynamicGrid
{
///
/// Interaction logic for DynamicEditorGrid.xaml
///
public delegate void OnUpdateOtherEditorHandler(string columnname, object value);
public delegate Dictionary EditorValueChangedHandler(object sender, string name, object value);
//public delegate Dictionary EditorGetLookupsHandler(object sender, String column);
public partial class DynamicEditorGrid : UserControl
{
public delegate void EditorCreatedHandler(object sender, double height, double width);
public delegate Document? FindDocumentEvent(string FileName);
public delegate Document? GetDocumentEvent(Guid id);
public delegate object? GetPropertyValueHandler(object sender, string name);
public delegate void SaveDocumentEvent(Document document);
public delegate void SetPropertyValueHandler(object sender, string name, object value);
// Column Definitions as defined by calling model
private DynamicGridColumns _columns;
private string _layoutname = "";
private bool _loaded;
private bool bChanging;
// List of Changed Editor Values (used when redesigning screen)
private readonly Dictionary changes = new();
private Grid CustomGrid;
private DynamicTabControl Details;
private Grid EditorGrid;
// Active Editor List
private readonly List editors = new();
private readonly Dictionary pagemap = new();
//Dictionary loadedpages = new Dictionary();
public DynamicEditorGrid()
{
InitializeComponent();
Loaded += DynamicEditorGrid_Loaded;
}
//private Dictionary> editors = new Dictionary>();
public DynamicEditorPages? Pages { get; private set; }
public bool PreloadPages { get; set; }
public Type UnderlyingType { get; set; }
public OnLoadPage? OnLoadPage { get; set; }
public OnSelectPage? OnSelectPage { get; set; }
public OnUnloadPage? OnUnloadPage { get; set; }
//private void UnloadEditorValues()
//{
// foreach (string columnname in editors.Keys)
// {
// bool changed = (bool)CoreUtils.GetPropertyValue(editors[columnname], "Changed");
// if (changed)
// {
// changes[columnname] = CoreUtils.GetPropertyValue(editors[columnname], "Value");
// Dictionary othervalues = CoreUtils.GetPropertyValue(editors[columnname], "OtherValues") as Dictionary;
// foreach (var field in othervalues.Keys)
// {
// List comps = columnname.Split('.').ToList();
// comps[comps.Count - 1] = field;
// String actualname = String.Join(".", comps);
// changes[actualname] = othervalues[field];
// }
// }
// }
//}
public bool IsCustomLayout { get; private set; }
public bool TryFindEditor(string columnname, [NotNullWhen(true)] out IDynamicEditorControl? editor)
{
editor = editors.FirstOrDefault(x => x.ColumnName.Equals(columnname));
return editor is not null;
}
public IDynamicEditorControl? FindEditor(string columnname)
{
TryFindEditor(columnname, out var editor);
return editor;
}
public object? GetPropertyValue(string columnname)
{
return OnGetPropertyValue?.Invoke(this, columnname);
}
public event EditorCreatedHandler? OnEditorCreated;
public event OnCustomiseColumns? OnCustomiseColumns;
public event OnGetEditor? OnGetEditor;
public event OnGridCustomiseEditor? OnGridCustomiseEditor;
public event OnGetEditorSequence? OnGetSequence;
public event GetPropertyValueHandler? OnGetPropertyValue;
public event SetPropertyValueHandler? OnSetPropertyValue;
public event EditorValueChangedHandler? OnEditorValueChanged;
public event OnReconfigureEditors? ReconfigureEditors;
public event OnDefineFilter? OnDefineFilter;
public event OnDefineLookup? OnDefineLookups;
public event OnLookupsDefined? OnLookupsDefined;
public event GetDocumentEvent? OnGetDocument;
public event FindDocumentEvent? OnFindDocument;
public event SaveDocumentEvent? OnSaveDocument;
private void DynamicEditorGrid_Loaded(object sender, RoutedEventArgs e)
{
ConfigureEditors();
LoadEditorValues();
AddPages();
DoReconfigureEditors();
//MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
//MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
//if (Keyboard.PrimaryDevice != null)
//{
// if (Keyboard.PrimaryDevice.ActiveSource != null)
// {
// var e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Tab) { RoutedEvent = Keyboard.KeyDownEvent };
// InputManager.Current.ProcessInput(e1);
// }
//}
editors.FirstOrDefault()?.SetFocus();
_loaded = true;
}
private void LoadLookupColumns(DynamicGridColumn column, Dictionary othercolumns)
{
othercolumns.Clear();
var comps = column.ColumnName.Split('.').ToList();
comps.RemoveAt(comps.Count - 1);
var prefix = string.Format("{0}.", string.Join(".", comps));
var cols = _columns.Where(x => !x.ColumnName.Equals(column.ColumnName) && x.ColumnName.StartsWith(prefix));
foreach (var col in cols)
othercolumns[col.ColumnName.Replace(prefix, "")] = col.ColumnName;
}
private string GetCodeColumn(DynamicGridColumn column)
{
var comps = column.ColumnName.Split('.').ToList();
comps.RemoveAt(comps.Count - 1);
var prefix = string.Format("{0}.", string.Join(".", comps));
var cols = _columns.Where(x => !x.ColumnName.Equals(column.ColumnName) && x.ColumnName.StartsWith(prefix));
foreach (var col in cols)
{
var editor = OnGetEditor?.Invoke(col);
if (editor is CodeEditor || editor is UniqueCodeEditor)
return col.ColumnName.Split('.').Last();
}
return "";
}
private void ConfigurePopupEditor(PopupEditorControl popup, DynamicGridColumn column, PopupEditor editor)
{
popup.ColumnName = column.ColumnName;
LoadLookupColumns(column, popup.OtherColumns);
if (popup.EditorDefinition is DataLookupEditor dataLookup)
LoadLookupColumns(column, dataLookup.OtherColumns);
popup.OnUpdateOtherEditor += Lookup_OnUpdateOtherEditor;
}
private void ConfigureCodePopupEditor(CodePopupEditorControl popup, DynamicGridColumn column, CodePopupEditor editor)
{
popup.ColumnName = column.ColumnName;
LoadLookupColumns(column, popup.OtherColumns);
if (popup.EditorDefinition is DataLookupEditor dataLookup)
LoadLookupColumns(column, dataLookup.OtherColumns);
popup.CodeColumn = !string.IsNullOrEmpty(editor.CodeColumn) ? editor.CodeColumn : GetCodeColumn(column);
popup.OnDefineFilter += (sender, type) => { return OnDefineFilter?.Invoke(sender, type); };
popup.OnUpdateOtherEditor += Lookup_OnUpdateOtherEditor;
}
private void ConfigureLookupEditor(LookupEditorControl lookup, DynamicGridColumn column, LookupEditor editor)
{
if (editor.LookupWidth != int.MaxValue)
lookup.Width = editor.LookupWidth;
lookup.ColumnName = column.ColumnName;
LoadLookupColumns(column, lookup.OtherColumns);
if (lookup.EditorDefinition is DataLookupEditor dataLookup)
LoadLookupColumns(column, dataLookup.OtherColumns);
lookup.OnUpdateOtherEditor += Lookup_OnUpdateOtherEditor;
lookup.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
lookup.OnLookupsDefined += sender => { OnLookupsDefined?.Invoke(sender); };
}
private void ConfigureEnumEditor(LookupEditorControl lookup, DynamicGridColumn column, EnumLookupEditor editor)
{
if (editor.LookupWidth != int.MaxValue)
lookup.Width = editor.LookupWidth;
lookup.ColumnName = column.ColumnName;
lookup.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
lookup.OnLookupsDefined += sender =>
{
//OnLookupsDefined?.Invoke(sender);
};
}
private void ConfigureComboEditor(LookupEditorControl lookup, DynamicGridColumn column, ComboLookupEditor editor)
{
if (editor.LookupWidth != int.MaxValue)
lookup.Width = editor.LookupWidth;
lookup.ColumnName = column.ColumnName;
lookup.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
lookup.OnLookupsDefined += sender => { OnLookupsDefined?.Invoke(sender); };
}
private void ConfigureMultiLookupEditor(MultiLookupEditorControl lookup, DynamicGridColumn column, ComboMultiLookupEditor editor)
{
if (editor.LookupWidth != int.MaxValue)
lookup.Width = editor.LookupWidth;
lookup.ColumnName = column.ColumnName;
lookup.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
lookup.OnLookupsDefined += sender => { OnLookupsDefined?.Invoke(sender); };
}
private void ConfigureCheckListEditor(CheckListBoxEditorControl checks, DynamicGridColumn column, CheckListEditor editor)
{
checks.Width = editor.LookupWidth;
checks.ColumnName = column.ColumnName;
checks.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
checks.OnLookupsDefined += sender => { OnLookupsDefined?.Invoke(sender); };
}
private void ConfigureDocumentEditor(DocumentEditorControl document, DynamicGridColumn column, BaseDocumentEditor editor)
{
document.ColumnName = column.ColumnName;
LoadLookupColumns(column, document.OtherColumns);
if (document.EditorDefinition is DataLookupEditor dataLookup)
LoadLookupColumns(column, dataLookup.OtherColumns);
document.OnGetDocument += id => { return OnGetDocument?.Invoke(id); };
document.OnSaveDocument += doc => { OnSaveDocument?.Invoke(doc); };
document.OnFindDocument += file => { return OnFindDocument?.Invoke(file); };
document.OnUpdateOtherEditor += Lookup_OnUpdateOtherEditor;
document.Filter = editor.FileMask;
}
private void ConfigurePasswordEditor(PasswordEditorControl passwordEditorControl, DynamicGridColumn column, PasswordEditor passwordEditor)
{
passwordEditorControl.ViewButtonVisible = passwordEditor.ViewButtonVisible;
}
//private IEnumerable FindEditors(FrameworkElement element, DynamicGridColumn column)
//{
// if (element == null)
// return new List();
// if ((element is Border) && ((element as Border).Child is ScrollViewer))
// return FindEditors(((element as Border).Child as ScrollViewer), column);
// return element.FindVisualChildren().Where(x => x.ColumnName != null && x.ColumnName.Equals(column.ColumnName));
//}
private IEnumerable FindEditors(DynamicGridColumn column)
{
var results = new List();
foreach (DynamicTabItem tab in Details.Items)
{
var border = tab.Content as Border;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null)
{
var grid = scroll.Content as Grid;
if (grid != null)
results.AddRange(grid.Children.OfType()
.Where(x => string.Equals(x.ColumnName, column.ColumnName)));
}
}
}
//results.AddRange(FindEditors(tab.Content as FrameworkElement, column));
return results;
}
private void ConfigureEditors()
{
if (editors.Any() && _columns != null)
foreach (var column in _columns)
{
var editorname = column.ColumnName.Replace(".", "_");
var
Editors = FindEditors(
column); //Details.FindVisualChildren().Where(x => x.ColumnName != null && x.ColumnName.Equals(column.ColumnName));
foreach (var Editor in Editors)
{
var editor = Editor.EditorDefinition;
//List parameters = editor.Parameters != null ? editor.Parameters.ToList() : new List();
if (Editor is LookupEditorControl lookupControl)
{
if (editor is LookupEditor lookupEditor)
ConfigureLookupEditor(lookupControl, column, lookupEditor);
else if (editor is EnumLookupEditor enumEditor)
ConfigureEnumEditor(lookupControl, column, enumEditor);
else if (editor is ComboLookupEditor comboEditor)
ConfigureComboEditor(lookupControl, column, comboEditor);
}
else if(Editor is MultiLookupEditorControl multiLookupEditor && editor is ComboMultiLookupEditor comboMultiLookup)
{
ConfigureMultiLookupEditor(multiLookupEditor, column, comboMultiLookup);
}
else if (Editor is CheckListBoxEditorControl checkBoxControl && editor is CheckListEditor checkListEditor)
{
ConfigureCheckListEditor(checkBoxControl, column, checkListEditor);
}
else if (Editor is PopupEditorControl popupControl && editor is PopupEditor popupEditor)
{
ConfigurePopupEditor(popupControl, column, popupEditor);
}
else if (Editor is CodePopupEditorControl codePopupControl && editor is CodePopupEditor codePopupEditor)
{
ConfigureCodePopupEditor(codePopupControl, column, codePopupEditor);
}
else if (Editor is DocumentEditorControl documentEditorControl && editor is BaseDocumentEditor baseDocumentEditor)
{
ConfigureDocumentEditor(documentEditorControl, column, baseDocumentEditor);
}
else if (Editor is PasswordEditorControl passwordEditorControl && editor is PasswordEditor passwordEditor)
{
ConfigurePasswordEditor(passwordEditorControl, column, passwordEditor);
}
Editor.Configure();
if (!editors.Any(x => x.ColumnName.Equals(Editor.ColumnName)))
editors.Add(Editor);
Editor.Loaded = true;
}
}
}
private bool LoadLayout(string xaml)
{
if (!string.IsNullOrWhiteSpace(xaml))
try
{
IsCustomLayout = true;
Content = null;
Details = (XamlReader.Parse(xaml) as DynamicTabControl) ?? throw new Exception("XAML is not a DynamicTabControl");
Content = Details;
Details.ApplyTemplate();
var iHeight = Details.Height > 0 ? Details.Height : 600;
var iWidth = Details.Width > 0 ? Details.Width : 800;
Details.Height = double.NaN;
Details.Width = double.NaN;
OnEditorCreated?.Invoke(this, iHeight, iWidth);
return true;
}
catch (Exception e)
{
MessageBox.Show(string.Format("Unable to Load XAML!\n\n{0}", e.Message));
}
return false;
}
private decimal GetSequence(DynamicGridColumn column)
{
if (OnGetSequence != null)
return OnGetSequence.Invoke(column);
return 999;
}
private void CreateLayout()
{
//Stopwatch sw = new Stopwatch();
//sw.Start();
IsCustomLayout = false;
Content = null;
Details = new DynamicTabControl();
Details.VerticalAlignment = VerticalAlignment.Stretch;
Details.HorizontalAlignment = HorizontalAlignment.Stretch;
Details.Name = "Details";
//Logger.Send(LogType.Information, "DEG.CreateLayout", String.Format("Created Tab Control: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
var EditorGrids = new Dictionary();
CustomGrid = EnsureGrid(EditorGrids, "Custom Fields");
EditorGrid = EnsureGrid(EditorGrids, "General");
//Logger.Send(LogType.Information, "DEG.CreateLayout", String.Format("Ensured Grids: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
Details.SelectionChanged += Details_SelectionChanged;
Content = Details;
editors.Clear();
double fGeneralHeight = 30; // Allow for Tab Header
//Logger.Send(LogType.Information, "DEG.CreateLayout", String.Format("Sorted Columns: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
foreach (var column in _columns.OrderBy(x => GetSequence(x)))
{
var iProp = DatabaseSchema.Property(UnderlyingType, column.ColumnName);
var editor = OnGetEditor?.Invoke(column);
if (editor != null && iProp?.ShouldShowEditor() != true)
{
editor.Visible = Visible.Hidden;
editor.Editable = Editable.Hidden;
}
if(editor is not null)
{
OnGridCustomiseEditor?.Invoke(this, column, editor);
}
if (editor != null && editor.Editable != Editable.Hidden)
{
var page = string.IsNullOrWhiteSpace(editor.Page) ? iProp is StandardProperty ? "General" : "Custom Fields" : editor.Page;
var grid = EnsureGrid(EditorGrids, page);
//List parameters = editor.Parameters != null ? editor.Parameters.ToList() : new List();
//bool bParams = true;
BaseDynamicEditorControl? element = null;
element = editor switch
{
TextBoxEditor => new TextBoxEditorControl(),
Core.RichTextEditor => new RichTextEditorControl(),
URLEditor => new URLEditorControl(),
CodeEditor or UniqueCodeEditor => new CodeEditorControl(),
CheckBoxEditor => new CheckBoxEditorControl(),
DateTimeEditor => new DateTimeEditorControl(),
DateEditor dateEditor => new DateEditorControl { TodayVisible = dateEditor.TodayVisible },
TimeOfDayEditor => new TimeOfDayEditorControl { NowButtonVisible = false },
DurationEditor => new DurationEditorControl(),
NotesEditor => new NotesEditorControl(),
PINEditor => new PINEditorControl(),
CheckListEditor => new CheckListBoxEditorControl(),
MemoEditor => new MemoEditorControl(),
JsonEditor => new JsonEditorControl(),
LookupEditor => ClientFactory.IsSupported(((LookupEditor)editor).Type) ? new LookupEditorControl() : null,
PopupEditor => ClientFactory.IsSupported(((PopupEditor)editor).Type) ? new PopupEditorControl() : null,
CodePopupEditor => ClientFactory.IsSupported(((CodePopupEditor)editor).Type) ? new CodePopupEditorControl() : null,
EnumLookupEditor or ComboLookupEditor => new LookupEditorControl(),
ComboMultiLookupEditor => new MultiLookupEditorControl(),
EmbeddedImageEditor imageEditor => new EmbeddedImageEditorControl
{
MaximumHeight = imageEditor.MaximumHeight,
MaximumWidth = imageEditor.MaximumWidth,
MaximumFileSize = imageEditor.MaximumFileSize
},
FileNameEditor fileNameEditor => new FileNameEditorControl
{
Filter = fileNameEditor.FileMask,
AllowView = fileNameEditor.AllowView,
RequireExisting = fileNameEditor.RequireExisting
},
FolderEditor folderEditor => new FolderEditorControl
{
InitialFolder = folderEditor.InitialFolder
},
MiscellaneousDocumentEditor => new DocumentEditorControl(),
ImageDocumentEditor => new DocumentEditorControl(),
VectorDocumentEditor => new DocumentEditorControl(),
PDFDocumentEditor => new DocumentEditorControl(),
PasswordEditor => new PasswordEditorControl(),
CurrencyEditor => new CurrencyEditorControl(),
DoubleEditor => new DoubleEditorControl(),
IntegerEditor => new IntegerEditorControl(),
Core.ScriptEditor scriptEditor => new ScriptEditorControl
{
SyntaxLanguage = scriptEditor.SyntaxLanguage
},
TimestampEditor => new TimestampEditorControl(),
ColorEditor => new ColorEditorControl(),
FilterEditor filter => new FilterEditorControl { FilterType = filter.Type! },
ExpressionEditor expression => new ExpressionEditorControl(),
_ => null,
};
if (element != null)
{
element.EditorDefinition = editor; //22
element.IsEnabled = editor.Editable == Editable.Enabled;
if (!string.IsNullOrWhiteSpace(editor.ToolTip))
{
element.ToolTip = new ToolTip() { Content = editor.ToolTip };
}
var label = new Label();
label.Content = CoreUtils.Neatify(editor.Caption); // 2
label.Margin = new Thickness(0F, 0F, 0F, 0F);
label.HorizontalAlignment = HorizontalAlignment.Stretch;
label.VerticalAlignment = VerticalAlignment.Stretch;
label.HorizontalContentAlignment = HorizontalAlignment.Left;
label.VerticalContentAlignment = VerticalAlignment.Center;
label.SetValue(Grid.RowProperty, grid.RowDefinitions.Count);
label.SetValue(Grid.ColumnProperty, 0);
label.Visibility = string.IsNullOrWhiteSpace(editor.Caption) ? Visibility.Collapsed : Visibility.Visible;
grid.Children.Add(label);
element.ColumnName = column.ColumnName;
element.Color = editor is UniqueCodeEditor ? Color.FromArgb(0xFF, 0xF6, 0xC9, 0xE8) : Colors.LightYellow;
editors.Add(element);
element.Margin = new Thickness(5F, 2.5F, 5F, 2.5F);
double iHeight = element.DesiredHeight();
if (iHeight == int.MaxValue)
{
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
fGeneralHeight += grid == EditorGrid ? element.MinHeight + 5.0F : 0.0F;
}
else
{
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(iHeight + 5.0F) });
fGeneralHeight += grid == EditorGrid ? iHeight + 5.0F : 0.0F;
}
double iWidth = element.DesiredWidth();
if (iWidth == int.MaxValue)
{
element.HorizontalAlignment = HorizontalAlignment.Stretch;
}
else
{
element.HorizontalAlignment = HorizontalAlignment.Left;
element.Width = iWidth;
}
element.SetValue(Grid.RowProperty, grid.RowDefinitions.Count - 1);
element.SetValue(Grid.ColumnProperty, 1);
grid.Children.Add(element);
}
}
}
//Logger.Send(LogType.Information, "DEG.CreateLayout", String.Format("Created Editors: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
OnEditorCreated?.Invoke(this, fGeneralHeight, 800);
if(Details.Items[^1] is DynamicTabItem custom)
{
custom.Visibility = CustomGrid.Children.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
}
//Logger.Send(LogType.Information, "DEG.CreateLayout", String.Format("Finalised: {0}", sw.ElapsedMilliseconds));
//sw.Stop();
}
private Grid EnsureGrid(Dictionary grids, string caption)
{
if (grids.ContainsKey(caption))
return grids[caption];
// Create Editor, ScrollViewer and TabItem for Dynamic Editor
var result = new Grid
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
//Background = new SolidColorBrush(Colors.Blue),
Margin = new Thickness(0, 2.5, 0, 2.5)
};
result.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
result.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var scroll = new ScrollViewer
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
Padding = new Thickness(2)
};
scroll.Content = result;
var border = new Border
{
BorderBrush = new SolidColorBrush(Colors.Gray),
Background = new SolidColorBrush(Colors.White),
BorderThickness = new Thickness(0.75)
};
border.Child = scroll;
var tab = new DynamicTabItem();
tab.Header = caption;
tab.Content = border;
if (Details.Items.Count == 0)
Details.Items.Add(tab);
else
Details.Items.Insert(Details.Items.Count - 1, tab);
grids[caption] = result;
return result;
}
//List configuredpages = new List();
private void Details_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (bChanging || Details?.SelectedItem == null || e.OriginalSource != Details)
return;
bChanging = true;
try
{
var tab = Details.SelectedItem as DynamicTabItem;
if(tab is not null)
{
var page = tab.Content as IDynamicEditorPage;
if (page is not null)
{
if (!page.Ready)
using (new WaitCursor())
{
OnLoadPage?.Invoke(page);
}
}
else
{
if (!_loaded || e.RemovedItems.Count == 0 || e.AddedItems.Count == 0 || e.AddedItems?[0] == e.RemovedItems?[0])
return;
//if (!configuredpages.Contains(tab))
//{
// ConfigureEditors(eds);
// configuredpages.Add(tab);
//}
var selectedGrid = ((tab.Content as Border)?.Child as ScrollViewer)?.Content;
var eds = editors
.Where(x => x is BaseDynamicEditorControl control &&
control.Parent == selectedGrid)
.Select(x => (BaseDynamicEditorControl)x);
foreach (var ed in eds)
{
var editorvalue = ed.GetValue();
var entityvalue = OnGetPropertyValue?.Invoke(this, ed.ColumnName);
if (!Equals(editorvalue, entityvalue))
{
ed.Loaded = false;
ed.SetValue(entityvalue);
ed.Loaded = true;
}
}
}
OnSelectPage?.Invoke(tab, null);
}
}
finally
{
bChanging = false;
}
}
public void UnloadPages(bool saved)
{
if(Pages is not null)
foreach (var page in Pages)
if (page.Ready)
OnUnloadPage?.Invoke(page, saved);
}
private void Lookup_OnUpdateOtherEditor(string columnname, object value)
{
var editor = editors.FirstOrDefault(x => x.ColumnName.Equals(columnname));
if (editor != null)
CoreUtils.SetPropertyValue(editor, "Value", value);
}
private string FormatXML(string xml)
{
var result = "";
var mStream = new MemoryStream();
var writer = new XmlTextWriter(mStream, Encoding.Unicode);
var document = new XmlDocument();
try
{
// Load the XmlDocument with the XML.
document.LoadXml(xml);
writer.Formatting = Formatting.Indented;
// Write the XML into a formatting XmlTextWriter
document.WriteContentTo(writer);
writer.Flush();
mStream.Flush();
// Have to rewind the MemoryStream in order to read
// its contents.
mStream.Position = 0;
// Read MemoryStream contents into a StreamReader.
var sReader = new StreamReader(mStream);
// Extract the text from the StreamReader.
var formattedXml = sReader.ReadToEnd();
result = formattedXml;
}
catch (XmlException)
{
// Handle the exception
}
mStream.Close();
writer.Close();
return result;
}
public void EditLayout()
{
ClearPages();
//UnloadEditorValues();
var xaml = new GlobalConfiguration(_layoutname).Load().XAML;
if (string.IsNullOrWhiteSpace(xaml))
{
Details.Height = Details.ActualHeight;
Details.Width = Details.ActualWidth;
//xaml = XamlWriter.Save(GetParentWindow(Details));
xaml = XamlWriter.Save(Details);
}
xaml = FormatXML(xaml);
var scripteditor = new ScriptEditor(xaml, SyntaxLanguage.XAML);
if (scripteditor.ShowDialog() == true)
{
var layout = new ScreenLayout { XAML = scripteditor.Script };
new GlobalConfiguration(_layoutname).Save(layout);
Content = null;
if (!LoadLayout(layout.XAML))
if (!LoadLayout(xaml))
CreateLayout();
Details.ApplyTemplate();
Application.Current.Dispatcher.Invoke(() =>
{
ConfigureEditors();
LoadEditorValues();
AddPages();
DoReconfigureEditors();
}, DispatcherPriority.Render);
}
}
internal void ResetLayout()
{
new GlobalConfiguration(_layoutname).Delete();
ClearPages();
//UnloadEditorValues();
CreateLayout();
LoadEditorValues();
AddPages();
DoReconfigureEditors();
}
private void LoadEditor(string columnname, object value)
{
}
private void EditorValueChanged(IDynamicEditorControl sender, Dictionary values)
{
//Logger.Send(LogType.Information, "", string.Format("DynamicEditorGrid.EditorValueChanged({0})", values.Keys.Count));
var changededitors = new Dictionary();
foreach (var key in values.Keys)
{
var changedcolumns = OnEditorValueChanged?.Invoke(this, key, values[key]);
if (changedcolumns != null)
foreach (var (change, value) in changedcolumns)
if (editors.Any(x => x.ColumnName.Equals(change)) && !changededitors.ContainsKey(change) && !change.Equals(sender.ColumnName))
changededitors[change] = value;
}
if (changededitors.Any())
LoadEditorValues(changededitors);
DoReconfigureEditors();
}
private void LoadEditorValues(Dictionary? changededitors = null)
{
var columnnames = changededitors != null ? changededitors.Keys.ToArray() : editors.Select(x => x.ColumnName).ToArray();
foreach (var columnname in columnnames)
{
var editor = editors.FirstOrDefault(x => x.ColumnName.Equals(columnname));
if (editor == null)
continue;
var bLoaded = editor.Loaded;
editor.Loaded = false;
if (changededitors != null && changededitors.ContainsKey(columnname))
{
CoreUtils.SetPropertyValue(editor, "Value", changededitors[columnname]);
}
else
{
var curvalue = OnGetPropertyValue?.Invoke(this, columnname);
try
{
CoreUtils.SetPropertyValue(editor, "Value", curvalue);
}
catch (Exception e)
{
MessageBox.Show($"Unable to set editor value for {columnname} -> {curvalue}: {CoreUtils.FormatException(e)}");
}
CoreUtils.SetPropertyValue(editor, "Changed", false);
}
editor.Loaded = bLoaded;
editor.OnEditorValueChanged += EditorValueChanged;
}
}
public virtual void DoReconfigureEditors()
{
ReconfigureEditors?.Invoke(this);
}
public void Load(string layoutname, DynamicEditorPages? pages = null)
{
_layoutname = layoutname;
Pages = pages;
//Stopwatch sw = new Stopwatch();
//sw.Start();
_columns = OnCustomiseColumns?.Invoke(this, null) ?? new DynamicGridColumns();
//Logger.Send(LogType.Information, "DEG.Load", String.Format("Loaded Columns: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
var layout = new GlobalConfiguration(_layoutname).Load();
//Logger.Send(LogType.Information, "DEG.Load", String.Format("Loaded Layout: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
if (!LoadLayout(layout.XAML))
CreateLayout();
//Logger.Send(LogType.Information, "DEG.Load", String.Format("Created Layout: {0}", sw.ElapsedMilliseconds));
//sw.Restart();
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
foreach (var columnname in editors.Select(x => x.ColumnName).ToArray())
{
var editor = editors.FirstOrDefault(x => x.ColumnName.Equals(columnname));
if(editor is not null)
{
editor.Loaded = true;
}
}
}
public bool Unload()
{
ClearPages();
var bChanged = false;
foreach (var columnname in changes.Keys)
{
OnSetPropertyValue?.Invoke(this, columnname, changes[columnname]);
bChanged = true;
}
return bChanged;
}
private void AddPages()
{
if (Pages != null)
using (new WaitCursor())
{
foreach (var page in Pages.OrderBy(x => x.Order()).ThenBy(x => x.Caption()))
{
var tab = new DynamicTabItem();
tab.Header = page.Caption();
tab.Content = page;
Details.Items.Insert(Details.Items.Count - 1, tab);
pagemap[page] = tab;
if (PreloadPages)
OnLoadPage?.Invoke(page);
page.EditorGrid = this;
}
}
//if (Details.Items.Count <= 2)
// ((TabItem)Details.Items[0]).Visibility = Visibility.Collapsed;
}
private void ClearPages()
{
foreach (var page in pagemap.Keys)
{
var tab = pagemap[page];
tab.Content = null;
Details.Items.Remove(tab);
}
pagemap.Clear();
//if (_pages != null)
//{
// foreach (var page in _pages)
// {
// var tab = Details.Items.OfType().FirstOrDefault(x => x.Content.Equals(page));
// if (tab != null)
// {
// tab.Content = null;
// Details.Items.Remove(tab);
// }
// }
//}
}
}
}