Browse Source

Fixed some problems with event handlers in meeting screen.

Kenric Nugteren 2 years ago
parent
commit
d382dc6bbe

+ 20 - 21
inabox.wpf/DynamicGrid/DynamicEditorForm.xaml.cs

@@ -33,25 +33,24 @@ namespace InABox.DynamicGrid
 
         public event OnValidateData? OnValidateData;
 
-        public event OnCustomiseColumns? OnCustomiseColumns;
-        public event OnDefineFilter? OnDefineFilter;
+        public OnCustomiseColumns? OnCustomiseColumns { set; }
+        public OnDefineFilter? OnDefineFilter { set; }
 
-        public event OnDefineLookup? OnDefineLookups;
+        public OnDefineLookup? OnDefineLookups { set; }
 
-        public event DefineEditorEventHandler? OnDefineEditor;
-        public event OnFormCustomiseEditor? OnFormCustomiseEditor;
-        public event OnReconfigureEditors? OnReconfigureEditors;
+        public DefineEditorEventHandler? OnDefineEditor { set; }
+        public OnFormCustomiseEditor? OnFormCustomiseEditor { set; }
+        public OnReconfigureEditors? OnReconfigureEditors { set; }
 
         public event OnAfterEditorValueChanged? OnAfterEditorValueChanged;
         public event EditorValueChangedHandler? OnEditorValueChanged;
 
-        public event GetDocumentEvent? OnGetDocument;
-        public event FindDocumentEvent? OnFindDocument;
-        public event SaveDocumentEvent? OnSaveDocument;
+        public GetDocumentEvent? OnGetDocument { set; }
+        public FindDocumentEvent? OnFindDocument { set; }
+        public SaveDocumentEvent? OnSaveDocument { set; }
 
         public event OnSelectPage? OnSelectPage;
-
-        public event DynamicGridSaveEvent? OnSaveItem;
+        public DynamicGridSaveEvent? OnSaveItem { set; }
 
         DynamicEditorPages? Pages { get; }
 
@@ -128,25 +127,25 @@ namespace InABox.DynamicGrid
 
         public event OnValidateData? OnValidateData { add => Form.OnValidateData += value; remove => Form.OnValidateData -= value; }
 
-        public event OnCustomiseColumns? OnCustomiseColumns { add => Form.OnCustomiseColumns += value; remove => Form.OnCustomiseColumns -= value; }
-        public event OnDefineFilter? OnDefineFilter { add => Form.OnDefineFilter += value; remove => Form.OnDefineFilter -= value; }
+        public OnCustomiseColumns? OnCustomiseColumns { get => Form.OnCustomiseColumns; set { Form.OnCustomiseColumns = value; } }
+        public OnDefineFilter? OnDefineFilter { get => Form.OnDefineFilter; set { Form.OnDefineFilter = value; } }
 
-        public event OnDefineLookup? OnDefineLookups { add => Form.OnDefineLookups += value; remove => Form.OnDefineLookups -= value; }
+        public OnDefineLookup? OnDefineLookups { get => Form.OnDefineLookups; set { Form.OnDefineLookups = value; } }
 
-        public event DefineEditorEventHandler? OnDefineEditor { add => Form.OnDefineEditor += value; remove => Form.OnDefineEditor -= value; }
-        public event OnFormCustomiseEditor? OnFormCustomiseEditor { add => Form.OnFormCustomiseEditor += value; remove => Form.OnFormCustomiseEditor -= value; }
-        public event OnReconfigureEditors? OnReconfigureEditors { add => Form.OnReconfigureEditors += value; remove => Form.OnReconfigureEditors -= value; }
+        public DefineEditorEventHandler? OnDefineEditor { get => Form.OnDefineEditor; set { Form.OnDefineEditor = value; } }
+        public OnFormCustomiseEditor? OnFormCustomiseEditor { get => Form.OnFormCustomiseEditor; set { Form.OnFormCustomiseEditor = value; } }
+        public OnReconfigureEditors? OnReconfigureEditors { get => Form.OnReconfigureEditors; set { Form.OnReconfigureEditors = value; } }
         
         public event OnAfterEditorValueChanged? OnAfterEditorValueChanged { add => Form.OnAfterEditorValueChanged += value; remove => Form.OnAfterEditorValueChanged -= value; }
         public event EditorValueChangedHandler? OnEditorValueChanged { add => Form.OnEditorValueChanged += value; remove => Form.OnEditorValueChanged -= value; }
 
-        public event IDynamicEditorForm.GetDocumentEvent? OnGetDocument { add => Form.OnGetDocument += value; remove => Form.OnGetDocument -= value; }
-        public event IDynamicEditorForm.FindDocumentEvent? OnFindDocument { add => Form.OnFindDocument += value; remove => Form.OnFindDocument -= value; }
-        public event IDynamicEditorForm.SaveDocumentEvent? OnSaveDocument { add => Form.OnSaveDocument += value; remove => Form.OnSaveDocument -= value; }
+        public IDynamicEditorForm.GetDocumentEvent? OnGetDocument { get => Form.OnGetDocument; set { Form.OnGetDocument = value; } }
+        public IDynamicEditorForm.FindDocumentEvent? OnFindDocument { get => Form.OnFindDocument; set { Form.OnFindDocument = value; } }
+        public IDynamicEditorForm.SaveDocumentEvent? OnSaveDocument { get => Form.OnSaveDocument; set { Form.OnSaveDocument = value; } }
 
         public event OnSelectPage? OnSelectPage { add => Form.OnSelectPage += value; remove => Form.OnSelectPage -= value; }
 
-        public event DynamicGridSaveEvent? OnSaveItem { add => Form.OnSaveItem += value; remove => Form.OnSaveItem -= value; }
+        public DynamicGridSaveEvent? OnSaveItem { get => Form.OnSaveItem; set { Form.OnSaveItem = value; } }
 
 
         public IDynamicEditorControl FindEditor(string columnName) => Form.FindEditor(columnName);

+ 2 - 2
inabox.wpf/DynamicGrid/DynamicEditorGrid.xaml.cs

@@ -65,8 +65,8 @@ namespace InABox.DynamicGrid
         public Type UnderlyingType { get; set; }
 
         public OnLoadPage? OnLoadPage { get; set; }
-        public OnSelectPage? OnSelectPage { get; set; }
-        public OnUnloadPage? OnUnloadPage { get; set; }
+        public event OnSelectPage? OnSelectPage;
+        public event OnUnloadPage? OnUnloadPage;
 
         public DynamicGridColumns Columns => _columns;
 

+ 15 - 17
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -2487,26 +2487,24 @@ namespace InABox.DynamicGrid
         {
         }
         
-        public DynamicEditorPages Pages { get; private set; }
-
         public override void InitialiseEditorForm(IDynamicEditorForm editor, T[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false)
         {
-            Pages = items.Length == 1 ? LoadEditorPages(items.First()) : new DynamicEditorPages();
+            var pages = items.Length == 1 ? LoadEditorPages(items.First()) : new DynamicEditorPages();
 
             var buttons = new DynamicEditorButtons();
             if (items.Length == 1)
                 LoadEditorButtons(items.First(), buttons);
 
-            editor.Setup(items.Any() ? items.First().GetType() : typeof(T), Pages, buttons, pageDataHandler, preloadPages);
+            editor.Setup(items.Any() ? items.First().GetType() : typeof(T), pages, buttons, pageDataHandler, preloadPages);
 
-            editor.OnCustomiseColumns += (sender, columns) =>
+            editor.OnCustomiseColumns = (sender, columns) =>
             {
                 columns.Clear();
                 columns.AddRange(MasterColumns);
                 ConfigureColumns(columns);
             };
 
-            editor.OnDefineEditor += (o, c) =>
+            editor.OnDefineEditor = (o, c) =>
             {
                 var result = GetEditor(o, c);
 
@@ -2516,28 +2514,28 @@ namespace InABox.DynamicGrid
                 return result;
             };
 
-            editor.OnFormCustomiseEditor += (o, i, c, e) => OnCustomiseEditor?.Invoke(o, (T[])i, c, e);
+            editor.OnFormCustomiseEditor = (o, i, c, e) => OnCustomiseEditor?.Invoke(o, (T[])i, c, e);
 
-            editor.OnDefineFilter += (type) => { return DefineFilter(type, items); };
+            editor.OnDefineFilter = (type) => { return DefineFilter(type, items); };
 
             //editor.OnDefineFilter += (o, e) => { return DefineFilter(items, e); };
-            editor.OnDefineLookups += editor => { DefineLookups(editor, items); };
+            editor.OnDefineLookups = editor => DefineLookups(editor, items);
 
-            editor.OnEditorValueChanged += (s, n, v) => { return EditorValueChanged(editor, items, n, v); };
+            editor.OnEditorValueChanged += (s, n, v) => EditorValueChanged(editor, items, n, v);
 
-            editor.OnAfterEditorValueChanged += (g, n) => { return AfterEditorValueChanged(g, items, n); }; 
+            editor.OnAfterEditorValueChanged += (g, n) => AfterEditorValueChanged(g, items, n);
             
-            editor.OnReconfigureEditors += g => { ReconfigureEditors(g, items); };
+            editor.OnReconfigureEditors = g => ReconfigureEditors(g, items);
 
-            editor.OnValidateData += (o, i) => { return ValidateData(items); };
+            editor.OnValidateData += (o, i) => ValidateData(items);
 
             editor.OnSelectPage += SelectPage;
 
-            editor.OnGetDocument += LoadDocument;
-            editor.OnFindDocument += FindDocument;
-            editor.OnSaveDocument += SaveDocument;
+            editor.OnGetDocument = LoadDocument;
+            editor.OnFindDocument = FindDocument;
+            editor.OnSaveDocument = SaveDocument;
 
-            editor.OnSaveItem += (o, e) =>
+            editor.OnSaveItem = (o, e) =>
             {
                 try
                 {

+ 1 - 0
inabox.wpf/DynamicGrid/Editors/DateEditor/DateEditorControl.cs

@@ -67,6 +67,7 @@ namespace InABox.DynamicGrid
             Editor.GotFocus += (o, e) => { new Timer(s => { Dispatcher.Invoke(() => { Editor.SelectAll(); }); }, Editor, 100, Timeout.Infinite); };
             Editor.ValueChanged += (o, e) =>
             {
+                if (e.OriginalSource != Editor) return;
                 if (Editor.Value.HasValue && Editor.Value.Value.Year < 100)
                     Editor.Value = Editor.Value.Value.AddYears(2000);
                 CheckChanged();

+ 2 - 1
inabox.wpf/DynamicGrid/Editors/TextBoxEditor/TextBoxEditorControl.cs

@@ -49,7 +49,8 @@ namespace InABox.DynamicGrid
 
             Editor.TextChanged += (o, e) =>
             {
-                IsChanged = true;
+                if(Loaded)
+                    IsChanged = true;
                 //CheckChanged();
             };
             Editor.LostFocus += (o, e) =>

+ 17 - 1
inabox.wpf/DynamicGrid/EmbeddedDynamicEditorForm.xaml

@@ -21,7 +21,23 @@
 
         <local:DynamicEditorGrid x:Name="Editor"
                                  Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="5,5,5,0"
-                                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
+                                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
+                                 OnCustomiseColumns="Editor_OnCustomiseColumns"
+                                 OnDefineFilter="Editor_OnDefineFilter"
+                                 OnEditorCreated="Editor_OnEditorCreated"
+                                 OnSelectPage="Editor_OnSelectPage"
+                                 OnUnloadPage="Editor_OnUnloadPage"
+                                 OnAfterEditorValueChanged="Editor_OnAfterEditorValueChanged"
+                                 OnReconfigureEditors="Editor_OnReconfigureEditors"
+                                 OnGridCustomiseEditor="Editor_OnGridCustomiseEditor"
+                                 OnGetSequence="Editor_OnGetSequence"
+                                 OnEditorValueChanged="EditorValueChanged"
+                                 OnDefineLookups="Editor_OnDefineLookups"
+                                 OnGetDocument="Editor_OnGetDocument" OnFindDocument="Editor_OnFindDocument" OnSaveDocument="Editor_OnSaveDocument"
+                                 GetItems="Editor_GetItems"
+                                 OnGetEditor="Editor_OnGetEditor"
+                                 OnGetPropertyValue="Editor_OnGetPropertyValue"
+                                 OnSetPropertyValue="Editor_OnSetPropertyValue"/>
 
         <StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" Orientation="Horizontal"
                     x:Name="Buttons">

+ 165 - 194
inabox.wpf/DynamicGrid/EmbeddedDynamicEditorForm.xaml.cs

@@ -100,27 +100,27 @@ namespace InABox.DynamicGrid
 
         public event OnValidateData? OnValidateData;
 
-        public event OnCustomiseColumns? OnCustomiseColumns;
-        public event OnDefineFilter? OnDefineFilter;
+        public OnCustomiseColumns? OnCustomiseColumns { get; set; }
+        public OnDefineFilter? OnDefineFilter { get; set; }
 
-        public event OnDefineLookup? OnDefineLookups;
+        public OnDefineLookup? OnDefineLookups { get; set; }
 
-        public event DefineEditorEventHandler? OnDefineEditor;
-        public event OnFormCustomiseEditor? OnFormCustomiseEditor;
-        public event OnReconfigureEditors? OnReconfigureEditors;
+        public DefineEditorEventHandler? OnDefineEditor { get; set; }
+        public OnFormCustomiseEditor? OnFormCustomiseEditor { get; set; }
+        public OnReconfigureEditors? OnReconfigureEditors { get; set; }
 
         public event EditorValueChangedHandler? OnEditorValueChanged;
         public event OnAfterEditorValueChanged? OnAfterEditorValueChanged;
 
-        public event IDynamicEditorForm.GetDocumentEvent? OnGetDocument;
-        public event IDynamicEditorForm.FindDocumentEvent? OnFindDocument;
-        public event IDynamicEditorForm.SaveDocumentEvent? OnSaveDocument;
+        public IDynamicEditorForm.GetDocumentEvent? OnGetDocument { get; set; }
+        public IDynamicEditorForm.FindDocumentEvent? OnFindDocument { get; set; }
+        public IDynamicEditorForm.SaveDocumentEvent? OnSaveDocument { get; set; }
 
         public event OnSelectPage? OnSelectPage;
 
-        public event DynamicGridSaveEvent? OnSaveItem;
+        public DynamicGridSaveEvent? OnSaveItem { get; set; }
 
-        public event DynamicEditorGrid.EditorCreatedHandler? OnEditorCreated;
+        public DynamicEditorGrid.EditorCreatedHandler? OnEditorCreated;
 
         public event OKEvent? OnOK;
         public event CancelEvent? OnCancel;
@@ -145,201 +145,34 @@ namespace InABox.DynamicGrid
             Setup(type, pages, buttons, PageDataHandler, PreloadPages);
         }
 
+        private IFilter? Editor_OnDefineFilter(Type type)
+        {
+            return OnDefineFilter?.Invoke(type);
+        }
+
+        private void ClearEvents()
+        {
+            OnEditorValueChanged = null;
+            OnAfterEditorValueChanged = null;
+            OnSelectPage = null;
+            OnValidateData = null;
+        }
+
         public void Setup(Type type, DynamicEditorPages? pages = null, DynamicEditorButtons? buttons = null,
             Func<Type, CoreTable>? PageDataHandler = null, bool PreloadPages = false)
         {
-            ReadOnly = false;
+            ClearEvents();
 
-            //this.Loaded += new RoutedEventHandler(ConfigureSystemMenu);
+            ReadOnly = false;
 
             Editor.UnderlyingType = type;
 
-            Editor.OnCustomiseColumns += Editor_OnCustomiseColumns;
-
-            Editor.OnDefineFilter += editor => OnDefineFilter?.Invoke(editor);
-
-            Editor.OnEditorCreated += Editor_OnEditorCreated;
-
-            Editor.OnLoadPage += page => { page.Load(Items.First(), PageDataHandler); };
-
-            Editor.OnSelectPage += (tab, items) => { OnSelectPage?.Invoke(tab, items); };
+            Editor.OnLoadPage = page => { page.Load(Items.First(), PageDataHandler); };
 
             Editor.PreloadPages = PreloadPages;
 
-            Editor.OnUnloadPage += (page, saved) =>
-            {
-                if (!saved)
-                    page.BeforeSave(Items.First());
-                else
-                    page.AfterSave(Items.First());
-            };
-
-            //Editor.OnGetPropertyInfo += (o, c) => { return CoreUtils.GetProperty(_item.GetType(), c); };
-
-            Editor.OnAfterEditorValueChanged += (g, n) => { return OnAfterEditorValueChanged?.Invoke(g, n); };
-
-            Editor.OnReconfigureEditors += g => { OnReconfigureEditors?.Invoke(g); };
-
-            Editor.OnGetEditor += c =>
-            {
-                if (_items != null && _items.Any())
-                {
-                    var property = DatabaseSchema.Property(type, c.ColumnName);
-                    if (property == null) return new NullEditor();
-
-                    if (property.Editor is NullEditor)
-                        return property.Editor;
-
-                    BaseEditor editor;
-                    if (property is CustomProperty)
-                    {
-                        editor = property.Editor.CloneEditor();
-                    }
-                    else
-                    {
-                        editor = OnDefineEditor?.Invoke(_items[0], c) ?? c.Editor.CloneEditor();
-                        var propEditor = property.Editor;
-                        editor.Page = propEditor.Page;
-                        editor.Caption = propEditor.Caption;
-                    }
-
-
-                    //defaultEditor.EditorSequence
-
-                    //EditorUtils.GetPropertyEditor(type, property, defaultEditor);
-
-                    /*BaseEditor editor = new NullEditor();
-                    var caption = "";
-                    var page = "";
-
-                    try
-                    {
-                        var comps = c.ColumnName.Split('.');
-                        for (var i = 0; i < comps.Length; i++)
-                        {
-                            var column = string.Join(".", comps.Take(i + 1));
-                            var prop = CoreUtils.GetProperty(type, column);
-
-                            if (column.Equals(c.ColumnName))
-                            {
-                                if (OnDefineEditor != null)
-                                    editor = OnDefineEditor(_items[0], c);
-                                else
-                                    editor = c.Editor != null ? c.Editor : new NullEditor();
-                            }
-                            else
-                            {
-                                var pedit = prop.GetEditor();
-                                if (pedit is NullEditor)
-                                    return pedit;
-                            }
-
-                            editor = editor == null ? new NullEditor() : editor.Clone() as BaseEditor;
-
-                            var capattr = prop.GetCustomAttribute<Caption>();
-                            var subcap = capattr != null ? capattr.Text : comps[i];
-                            var path = capattr != null ? capattr.IncludePath : true;
-                            if (!string.IsNullOrWhiteSpace(subcap))
-                                caption = string.IsNullOrWhiteSpace(caption) || path == false ? subcap : string.Format("{0} {1}", caption, subcap);
-
-                            if (string.IsNullOrWhiteSpace(page))
-                            {
-                                var pageattr = prop.GetCustomAttribute<EditorSequence>();
-                                if (pageattr != null)
-                                    page = pageattr.Page;
-                            }
-                        }
-
-                        editor.Caption = caption;
-                        editor.Page = page;
-                    }
-                    catch (Exception e)
-                    {
-                        var dmprop = DatabaseSchema.Property(_items[0].GetType(), c.ColumnName);
-                        if (dmprop is CustomProperty)
-                        {
-                            editor = dmprop.Editor.Clone() as BaseEditor;
-                            editor.Caption = dmprop.Caption;
-                            editor.Page = string.IsNullOrWhiteSpace(dmprop.Page) ? "Custom Fields" : dmprop.Page;
-                        }
-                    }*/
-
-                    if (ReadOnly && editor.Editable.Equals(Editable.Enabled))
-                        editor.Editable = Editable.Disabled;
-                    return editor;
-                }
-
-                return new NullEditor();
-            };
-
-            Editor.OnGridCustomiseEditor += (sender, column, editor) => OnFormCustomiseEditor?.Invoke(this, Items, column, editor);
-
-            Editor.OnGetSequence += c => CoreUtils.GetPropertySequence(_items.First().GetType(), c.ColumnName);
-
-            Editor.OnGetPropertyValue += (o, c) =>
-            {
-                if (!_items.Any())
-                    return null;
-
-                object? result;
-                try
-                {
-                    result = CoreUtils.GetPropertyValue(_items.First(), c);
-                }
-                catch
-                {
-                    result = _items.First().UserProperties.ContainsKey(c) ? _items.First().UserProperties[c] : null;
-                }
-
-                if (result == null)
-                    return null;
-
-                foreach (var _item in _items)
-                {
-                    object? curvalue;
-                    try
-                    {
-                        curvalue = CoreUtils.GetPropertyValue(_item, c);
-                    }
-                    catch
-                    {
-                        curvalue = _item.UserProperties.ContainsKey(c) ? _item.UserProperties[c] : null;
-                    }
-
-                    if (curvalue == null)
-                        return null;
-
-                    if (!curvalue.Equals(result))
-                        return null;
-                }
-
-                return result;
-            };
-
-            Editor.OnSetPropertyValue += (o, c, v) =>
-            {
-                foreach (var _item in _items)
-                    if (_item.UserProperties.ContainsKey(c))
-                        _item.UserProperties[c] = v;
-                    else
-                        CoreUtils.SetPropertyValue(_item, c, v);
-            };
-
-            Editor.OnEditorValueChanged += EditorValueChanged;
-
-            Editor.OnDefineLookups += sender => { OnDefineLookups?.Invoke(sender); };
-
-            Editor.OnGetDocument += id => { return OnGetDocument?.Invoke(id); };
-            Editor.OnSaveDocument += doc => { OnSaveDocument?.Invoke(doc); };
-            Editor.OnFindDocument += file => { return OnFindDocument?.Invoke(file); };
-
-            Editor.GetItems += () => _items;
-
             Pages = pages ?? new DynamicEditorPages();
 
-            if (Pages == null || Pages.Count == 0)
-                Editor.Margin = new Thickness(5, 5, 5, 0);
-
             Buttons.Children.Clear();
             if (buttons != null)
                 foreach (var button in buttons)
@@ -466,6 +299,144 @@ namespace InABox.DynamicGrid
 
         public void SetLayoutType<T>() where T : DynamicEditorGridLayout => Editor.SetLayoutType<T>();
 
+        private void Editor_OnSelectPage(DynamicEditorGrid sender, BaseObject[] items)
+        {
+            OnSelectPage?.Invoke(sender, items);
+        }
+
+        private void Editor_OnUnloadPage(IDynamicEditorPage page, bool saved)
+        {
+            if (!saved)
+                page.BeforeSave(Items.First());
+            else
+                page.AfterSave(Items.First());
+        }
+
+        private Dictionary<string, object?>? Editor_OnAfterEditorValueChanged(DynamicEditorGrid sender, string columnname)
+        {
+            return OnAfterEditorValueChanged?.Invoke(sender, columnname);
+        }
+
+        private void Editor_OnReconfigureEditors(DynamicEditorGrid sender)
+        {
+            OnReconfigureEditors?.Invoke(sender);
+        }
+
+        private void Editor_OnGridCustomiseEditor(DynamicEditorGrid sender, DynamicGridColumn column, BaseEditor editor)
+        {
+            OnFormCustomiseEditor?.Invoke(this, Items, column, editor);
+        }
+
+        private decimal Editor_OnGetSequence(DynamicGridColumn column)
+        {
+            return CoreUtils.GetPropertySequence(_items.First().GetType(), column.ColumnName);
+        }
+
+        private void Editor_OnDefineLookups(ILookupEditorControl editor)
+        {
+            OnDefineLookups?.Invoke(editor);
+        }
+
+        private Document? Editor_OnGetDocument(Guid id)
+        {
+            return OnGetDocument?.Invoke(id);
+        }
+
+        private Document? Editor_OnFindDocument(string file)
+        {
+            return OnFindDocument?.Invoke(file);
+        }
+
+        private void Editor_OnSaveDocument(Document document)
+        {
+            OnSaveDocument?.Invoke(document);
+        }
+
+        private object?[] Editor_GetItems()
+        {
+            return _items;
+        }
+
+        private BaseEditor Editor_OnGetEditor(DynamicGridColumn column)
+        {
+            if (_items != null && _items.Any())
+            {
+                var property = DatabaseSchema.Property(Editor.UnderlyingType, column.ColumnName);
+                if (property == null) return new NullEditor();
+
+                if (property.Editor is NullEditor)
+                    return property.Editor;
+
+                BaseEditor editor;
+                if (property is CustomProperty)
+                {
+                    editor = property.Editor.CloneEditor();
+                }
+                else
+                {
+                    editor = OnDefineEditor?.Invoke(_items[0], column) ?? column.Editor.CloneEditor();
+                    var propEditor = property.Editor;
+                    editor.Page = propEditor.Page;
+                    editor.Caption = propEditor.Caption;
+                }
+
+                if (ReadOnly && editor.Editable.Equals(Editable.Enabled))
+                    editor.Editable = Editable.Disabled;
+                return editor;
+            }
+
+            return new NullEditor();
+        }
+
+        private object? Editor_OnGetPropertyValue(object sender, string column)
+        {
+            if (!_items.Any())
+                return null;
+
+            object? result;
+            try
+            {
+                result = CoreUtils.GetPropertyValue(_items.First(), column);
+            }
+            catch
+            {
+                result = _items.First().UserProperties.ContainsKey(column) ? _items.First().UserProperties[column] : null;
+            }
+
+            if (result == null)
+                return null;
+
+            foreach (var _item in _items)
+            {
+                object? curvalue;
+                try
+                {
+                    curvalue = CoreUtils.GetPropertyValue(_item, column);
+                }
+                catch
+                {
+                    curvalue = _item.UserProperties.ContainsKey(column) ? _item.UserProperties[column] : null;
+                }
+
+                if (curvalue == null)
+                    return null;
+
+                if (!curvalue.Equals(result))
+                    return null;
+            }
+
+            return result;
+        }
+
+        private void Editor_OnSetPropertyValue(object sender, string column, object value)
+        {
+            foreach (var _item in _items)
+                if (_item.UserProperties.ContainsKey(column))
+                    _item.UserProperties[column] = value;
+                else
+                    CoreUtils.SetPropertyValue(_item, column, value);
+        }
+
         //public void EditLayout() => Editor.EditLayout();
         //public void ResetLayout() => Editor.ResetLayout();