Browse Source

Fixing bugs with DataEntryPanel.

Kenric Nugteren 5 tháng trước cách đây
mục cha
commit
3aaea255af

+ 316 - 317
inabox.wpf/DynamicGrid/Controls/DynamicSplitPanel.cs

@@ -9,409 +9,408 @@ using System.Windows.Input;
 using InABox.Core;
 using Syncfusion.Windows.Controls.Input;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+[Flags]
+public enum DynamicSplitPanelView
 {
-    [Flags]
-    public enum DynamicSplitPanelView
-    {
-        Master = 1,
-        Detail = 2,
-        Combined = 4
-    }
+    Master = 1,
+    Detail = 2,
+    Combined = 4
+}
 
-    public enum DynamicSplitPanelAnchor
-    {
-        Master,
-        Detail
-    }
+public enum DynamicSplitPanelAnchor
+{
+    Master,
+    Detail
+}
 
-    public class DynamicSplitPanelSettings : EventArgs
-    {
-        public DynamicSplitPanelView View { get; set; }
-        public double AnchorWidth { get; set; }
-        public double DetailHeight { get; set; }
-    }
+public class DynamicSplitPanelSettings : EventArgs
+{
+    public DynamicSplitPanelView View { get; set; }
+    public double AnchorWidth { get; set; }
+    public double DetailHeight { get; set; }
+}
 
-    public delegate void DynamicSplitPanelChanged(object sender, DynamicSplitPanelSettings e);
+public delegate void DynamicSplitPanelChanged(object sender, DynamicSplitPanelSettings e);
 
-    public class DynamicSplitPanel : Control
-    {
-        
-        public static readonly DependencyProperty AllowableViewsProperty = DependencyProperty.Register(
-            nameof(AllowableViews), 
-            typeof(DynamicSplitPanelView),
-            typeof(DynamicSplitPanel), 
-            new UIPropertyMetadata( DynamicSplitPanelView.Master | DynamicSplitPanelView.Combined | DynamicSplitPanelView.Detail ));
-        
-        public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(DynamicSplitPanelView),
-            typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelView.Detail));
+public class DynamicSplitPanel : Control
+{
+    
+    public static readonly DependencyProperty AllowableViewsProperty = DependencyProperty.Register(
+        nameof(AllowableViews), 
+        typeof(DynamicSplitPanelView),
+        typeof(DynamicSplitPanel), 
+        new UIPropertyMetadata( DynamicSplitPanelView.Master | DynamicSplitPanelView.Combined | DynamicSplitPanelView.Detail ));
+    
+    public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(DynamicSplitPanelView),
+        typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelView.Detail));
 
-        public static readonly DependencyProperty AnchorProperty = DependencyProperty.Register(nameof(Anchor), typeof(DynamicSplitPanelAnchor),
-            typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelAnchor.Master));
-        
-        public static readonly DependencyProperty AnchorWidthProperty =
-            DependencyProperty.Register(nameof(AnchorWidth), typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)300F));
+    public static readonly DependencyProperty AnchorProperty = DependencyProperty.Register(nameof(Anchor), typeof(DynamicSplitPanelAnchor),
+        typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelAnchor.Master));
+    
+    public static readonly DependencyProperty AnchorWidthProperty =
+        DependencyProperty.Register(nameof(AnchorWidth), typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)300F));
 
-        public static readonly DependencyProperty MasterCaptionProperty =
-            DependencyProperty.Register("MasterCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty MasterCaptionProperty =
+        DependencyProperty.Register("MasterCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty DetailCaptionProperty =
-            DependencyProperty.Register("DetailCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty DetailCaptionProperty =
+        DependencyProperty.Register("DetailCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty HeaderProperty =
-            DependencyProperty.Register("Header", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty HeaderProperty =
+        DependencyProperty.Register("Header", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty MasterProperty =
-            DependencyProperty.Register(nameof(Master), typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty MasterProperty =
+        DependencyProperty.Register(nameof(Master), typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty DetailHeaderProperty =
-            DependencyProperty.Register("DetailHeader", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty DetailHeaderProperty =
+        DependencyProperty.Register("DetailHeader", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty DetailProperty =
-            DependencyProperty.Register("Detail", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty DetailProperty =
+        DependencyProperty.Register("Detail", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        public static readonly DependencyProperty DetailHeightProperty =
-            DependencyProperty.Register("DetailHeight", typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)200F));
+    public static readonly DependencyProperty DetailHeightProperty =
+        DependencyProperty.Register("DetailHeight", typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)200F));
 
-        public static readonly DependencyProperty SecondaryDetailProperty = DependencyProperty.Register("SecondaryDetail", typeof(FrameworkElement),
-            typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
+    public static readonly DependencyProperty SecondaryDetailProperty = DependencyProperty.Register("SecondaryDetail", typeof(FrameworkElement),
+        typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
 
-        private Button CombinedLeft;
-        private Button CombinedRight;
+    private Button CombinedLeft;
+    private Button CombinedRight;
 
-        private Grid DetailGrid;
-        private Label DetailsHeader;
-        private Button DetailsOnly;
-        private SfGridSplitter DetailSplitter;
+    private Grid DetailGrid;
+    private Label DetailsHeader;
+    private Button DetailsOnly;
+    private SfGridSplitter DetailSplitter;
 
-        private Grid Grid;
-        private Label MasterHeader;
-        private Button MasterOnly;
-        private SfGridSplitter Splitter;
+    private Grid Grid;
+    private Label MasterHeader;
+    private Button MasterOnly;
+    private SfGridSplitter Splitter;
 
 
-        static DynamicSplitPanel()
+    static DynamicSplitPanel()
+    {
+        DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicSplitPanel), new FrameworkPropertyMetadata(typeof(DynamicSplitPanel)));
+    }
+    
+    public DynamicSplitPanelView AllowableViews
+    {
+        get => (DynamicSplitPanelView)GetValue(AllowableViewsProperty);
+        set
         {
-            DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicSplitPanel), new FrameworkPropertyMetadata(typeof(DynamicSplitPanel)));
+            SetValue(AllowableViewsProperty, value);
+            ConfigureScreen();
         }
         
-        public DynamicSplitPanelView AllowableViews
-        {
-            get => (DynamicSplitPanelView)GetValue(AllowableViewsProperty);
-            set
-            {
-                SetValue(AllowableViewsProperty, value);
-                ConfigureScreen();
-            }
-            
-        }    
-        
-        private bool IsViewAllowed(params DynamicSplitPanelView[] views)
+    }    
+    
+    private bool IsViewAllowed(params DynamicSplitPanelView[] views)
+    {
+        foreach (var view in views)
         {
-            foreach (var view in views)
-            {
-                if ((AllowableViews & view) == view)
-                    return true;
-            }
-            return false;
+            if ((AllowableViews & view) == view)
+                return true;
         }
+        return false;
+    }
 
-        public DynamicSplitPanelView View
+    public DynamicSplitPanelView View
+    {
+        get => (DynamicSplitPanelView)GetValue(ViewProperty);
+        set
         {
-            get => (DynamicSplitPanelView)GetValue(ViewProperty);
-            set
-            {
-                SetValue(ViewProperty, value);
-                ConfigureScreen();
-            }
+            SetValue(ViewProperty, value);
+            ConfigureScreen();
         }
+    }
 
-        public DynamicSplitPanelAnchor Anchor
+    public DynamicSplitPanelAnchor Anchor
+    {
+        get => (DynamicSplitPanelAnchor)GetValue(AnchorProperty);
+        set 
         {
-            get => (DynamicSplitPanelAnchor)GetValue(AnchorProperty);
-            set 
-            {
-                SetValue(AnchorProperty, value);
-                ConfigureScreen();
-            }
+            SetValue(AnchorProperty, value);
+            ConfigureScreen();
         }
-        
-        public double AnchorWidth
+    }
+    
+    public double AnchorWidth
+    {
+        get => (double)GetValue(AnchorWidthProperty);
+        set
         {
-            get => (double)GetValue(AnchorWidthProperty);
-            set
-            {
-                SetValue(AnchorWidthProperty, value);
-                ConfigureScreen();
-            }
+            SetValue(AnchorWidthProperty, value);
+            ConfigureScreen();
         }
+    }
 
-        public string MasterCaption
-        {
-            get => (string)GetValue(MasterCaptionProperty);
-            set => SetValue(MasterCaptionProperty, value);
-            //MasterHeader.Content = value;
-        }
+    public string MasterCaption
+    {
+        get => (string)GetValue(MasterCaptionProperty);
+        set => SetValue(MasterCaptionProperty, value);
+        //MasterHeader.Content = value;
+    }
 
-        public string DetailCaption
-        {
-            get => (string)GetValue(DetailCaptionProperty);
-            set => SetValue(DetailCaptionProperty, value);
-            //DetailHeader.Content = value;
-        }
+    public string DetailCaption
+    {
+        get => (string)GetValue(DetailCaptionProperty);
+        set => SetValue(DetailCaptionProperty, value);
+        //DetailHeader.Content = value;
+    }
 
-        public FrameworkElement Header
-        {
-            get => (FrameworkElement)GetValue(HeaderProperty);
-            set => SetValue(HeaderProperty, value);
-        }
+    public FrameworkElement Header
+    {
+        get => (FrameworkElement)GetValue(HeaderProperty);
+        set => SetValue(HeaderProperty, value);
+    }
 
-        public FrameworkElement Master
-        {
-            get => (FrameworkElement)GetValue(MasterProperty);
-            set => SetValue(MasterProperty, value);
-        }
+    public FrameworkElement Master
+    {
+        get => (FrameworkElement)GetValue(MasterProperty);
+        set => SetValue(MasterProperty, value);
+    }
 
-        public FrameworkElement DetailHeader
-        {
-            get => (FrameworkElement)GetValue(DetailHeaderProperty);
-            set => SetValue(DetailHeaderProperty, value);
-        }
+    public FrameworkElement DetailHeader
+    {
+        get => (FrameworkElement)GetValue(DetailHeaderProperty);
+        set => SetValue(DetailHeaderProperty, value);
+    }
 
-        public FrameworkElement Detail
-        {
-            get => (FrameworkElement)GetValue(DetailProperty);
-            set => SetValue(DetailProperty, value);
-        }
+    public FrameworkElement Detail
+    {
+        get => (FrameworkElement)GetValue(DetailProperty);
+        set => SetValue(DetailProperty, value);
+    }
 
-        public double DetailHeight
+    public double DetailHeight
+    {
+        get => (double)GetValue(DetailHeightProperty);
+        set
         {
-            get => (double)GetValue(DetailHeightProperty);
-            set
-            {
-                SetValue(DetailHeightProperty, value);
-                ConfigureScreen();
-            }
+            SetValue(DetailHeightProperty, value);
+            ConfigureScreen();
         }
+    }
 
-        public FrameworkElement SecondaryDetail
-        {
-            get => (FrameworkElement)GetValue(SecondaryDetailProperty);
-            set => SetValue(SecondaryDetailProperty, value);
-        }
+    public FrameworkElement SecondaryDetail
+    {
+        get => (FrameworkElement)GetValue(SecondaryDetailProperty);
+        set => SetValue(SecondaryDetailProperty, value);
+    }
 
-        public event DynamicSplitPanelChanged OnChanged;
+    public event DynamicSplitPanelChanged OnChanged;
 
-        private void RightClick(object sender, RoutedEventArgs e)
-        {
-            if (View == DynamicSplitPanelView.Detail)
-                View = DynamicSplitPanelView.Combined;
-            else if (View == DynamicSplitPanelView.Combined)
-                View = DynamicSplitPanelView.Master;
-            Changed();
-        }
+    private void RightClick(object sender, RoutedEventArgs e)
+    {
+        if (View == DynamicSplitPanelView.Detail)
+            View = DynamicSplitPanelView.Combined;
+        else if (View == DynamicSplitPanelView.Combined)
+            View = DynamicSplitPanelView.Master;
+        Changed();
+    }
 
-        private void LeftClick(object sender, RoutedEventArgs e)
-        {
-            if (View == DynamicSplitPanelView.Master)
-                View = DynamicSplitPanelView.Combined;
-            else if (View == DynamicSplitPanelView.Combined)
-                View = DynamicSplitPanelView.Detail;
-            Changed();
-        }
+    private void LeftClick(object sender, RoutedEventArgs e)
+    {
+        if (View == DynamicSplitPanelView.Master)
+            View = DynamicSplitPanelView.Combined;
+        else if (View == DynamicSplitPanelView.Combined)
+            View = DynamicSplitPanelView.Detail;
+        Changed();
+    }
 
-        public bool IsMasterVisible() => View == DynamicSplitPanelView.Master || View == DynamicSplitPanelView.Combined;
+    public bool IsMasterVisible() => View == DynamicSplitPanelView.Master || View == DynamicSplitPanelView.Combined;
 
-        public bool IsDetailVisible() => View == DynamicSplitPanelView.Detail || View == DynamicSplitPanelView.Combined;
+    public bool IsDetailVisible() => View == DynamicSplitPanelView.Detail || View == DynamicSplitPanelView.Combined;
 
-        private void ConfigureScreen()
+    private void ConfigureScreen()
+    {
+        CheckParts();
+        try
         {
-            CheckParts();
-            try
-            {
-                if (MasterHeader != null)
-                    MasterHeader.Content = MasterCaption;
-                
-                if (DetailsHeader != null)
-                    DetailsHeader.Content = DetailCaption;
+            if (MasterHeader != null)
+                MasterHeader.Content = MasterCaption;
+            
+            if (DetailsHeader != null)
+                DetailsHeader.Content = DetailCaption;
 
-                if (CombinedLeft != null)
-                    CombinedLeft.Visibility = View == DynamicSplitPanelView.Combined && AllowableViews.HasFlag(DynamicSplitPanelView.Master) ? Visibility.Visible : Visibility.Collapsed;
+            if (CombinedLeft != null)
+                CombinedLeft.Visibility = View == DynamicSplitPanelView.Combined && AllowableViews.HasFlag(DynamicSplitPanelView.Master) ? Visibility.Visible : Visibility.Collapsed;
 
-                if (CombinedRight != null)
-                    CombinedRight.Visibility = View == DynamicSplitPanelView.Combined && AllowableViews.HasFlag(DynamicSplitPanelView.Detail) ? Visibility.Visible : Visibility.Collapsed;
+            if (CombinedRight != null)
+                CombinedRight.Visibility = View == DynamicSplitPanelView.Combined && AllowableViews.HasFlag(DynamicSplitPanelView.Detail) ? Visibility.Visible : Visibility.Collapsed;
 
-                if (Grid != null)
-                {
-                    Grid.ColumnDefinitions[0].Width = (View == DynamicSplitPanelView.Detail) 
-                                                      && (Master != null) 
-                                                      && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Master))
-                        ? new GridLength(1.0F, GridUnitType.Auto)
-                        : new GridLength(0.0F, GridUnitType.Pixel);
-                    
-                    Grid.ColumnDefinitions[1].Width = Master == null 
-                        ? new GridLength(0.0F, GridUnitType.Pixel) 
-                        : View switch { 
-                            DynamicSplitPanelView.Master => new GridLength(1.0F, GridUnitType.Star),
-                            DynamicSplitPanelView.Detail => new GridLength(0.0F, GridUnitType.Pixel),
-                            _ => Anchor == DynamicSplitPanelAnchor.Master 
-                                ? new GridLength(AnchorWidth, GridUnitType.Pixel) 
-                                : new GridLength(1.0F, GridUnitType.Star)
-                        };
-                    
-                    Grid.ColumnDefinitions[2].Width = (View == DynamicSplitPanelView.Combined) 
-                                                      && (Master != null)
-                        ? new GridLength(1.0F, GridUnitType.Auto)
-                        : new GridLength(0.0F, GridUnitType.Pixel);
-
-                    Grid.ColumnDefinitions[3].Width = View switch
-                    {
-                        DynamicSplitPanelView.Master => new GridLength(0.0F, GridUnitType.Pixel),
-                        DynamicSplitPanelView.Detail => new GridLength(1.0F, GridUnitType.Star),
-                        _ => Anchor == DynamicSplitPanelAnchor.Detail
-                            ? new GridLength(AnchorWidth, GridUnitType.Pixel)
+            if (Grid != null)
+            {
+                Grid.ColumnDefinitions[0].Width = (View == DynamicSplitPanelView.Detail) 
+                                                  && (Master != null) 
+                                                  && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Master))
+                    ? new GridLength(1.0F, GridUnitType.Auto)
+                    : new GridLength(0.0F, GridUnitType.Pixel);
+                
+                Grid.ColumnDefinitions[1].Width = Master == null 
+                    ? new GridLength(0.0F, GridUnitType.Pixel) 
+                    : View switch { 
+                        DynamicSplitPanelView.Master => new GridLength(1.0F, GridUnitType.Star),
+                        DynamicSplitPanelView.Detail => new GridLength(0.0F, GridUnitType.Pixel),
+                        _ => Anchor == DynamicSplitPanelAnchor.Master 
+                            ? new GridLength(AnchorWidth, GridUnitType.Pixel) 
                             : new GridLength(1.0F, GridUnitType.Star)
                     };
-                        
-                    Grid.ColumnDefinitions[4].Width = (View == DynamicSplitPanelView.Master) 
-                                                      && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Detail))
-                        ? new GridLength(1.0F, GridUnitType.Auto)
-                        : new GridLength(0.0F, GridUnitType.Pixel);
-                    
-                    Grid.RowDefinitions[0].Height =
-                        Header == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
-                }
+                
+                Grid.ColumnDefinitions[2].Width = (View == DynamicSplitPanelView.Combined) 
+                                                  && (Master != null)
+                    ? new GridLength(1.0F, GridUnitType.Auto)
+                    : new GridLength(0.0F, GridUnitType.Pixel);
 
-                if (DetailGrid != null)
+                Grid.ColumnDefinitions[3].Width = View switch
                 {
-                    DetailGrid.SetValue(Grid.RowProperty, DetailHeader == null ? 0 : 1);
-                    DetailGrid.SetValue(Grid.RowSpanProperty, DetailHeader == null ? 2 : 1);
-                    DetailGrid.RowDefinitions[0].Height = SecondaryDetail == null
-                        ? new GridLength(1.0F, GridUnitType.Star)
-                        : new GridLength(DetailHeight, GridUnitType.Pixel);
-                    DetailGrid.RowDefinitions[1].Height =
-                        SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
-                    DetailGrid.RowDefinitions[2].Height =
-                        SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Star);
-                    DetailSplitter.IsEnabled = SecondaryDetail != null;
-                }
+                    DynamicSplitPanelView.Master => new GridLength(0.0F, GridUnitType.Pixel),
+                    DynamicSplitPanelView.Detail => new GridLength(1.0F, GridUnitType.Star),
+                    _ => Anchor == DynamicSplitPanelAnchor.Detail
+                        ? new GridLength(AnchorWidth, GridUnitType.Pixel)
+                        : new GridLength(1.0F, GridUnitType.Star)
+                };
+                    
+                Grid.ColumnDefinitions[4].Width = (View == DynamicSplitPanelView.Master) 
+                                                  && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Detail))
+                    ? new GridLength(1.0F, GridUnitType.Auto)
+                    : new GridLength(0.0F, GridUnitType.Pixel);
+                
+                Grid.RowDefinitions[0].Height =
+                    Header == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
+            }
 
+            if (DetailGrid != null)
+            {
+                DetailGrid.SetValue(Grid.RowProperty, DetailHeader == null ? 0 : 1);
+                DetailGrid.SetValue(Grid.RowSpanProperty, DetailHeader == null ? 2 : 1);
+                DetailGrid.RowDefinitions[0].Height = SecondaryDetail == null
+                    ? new GridLength(1.0F, GridUnitType.Star)
+                    : new GridLength(DetailHeight, GridUnitType.Pixel);
+                DetailGrid.RowDefinitions[1].Height =
+                    SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
+                DetailGrid.RowDefinitions[2].Height =
+                    SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Star);
+                DetailSplitter.IsEnabled = SecondaryDetail != null;
+            }
 
-                if (CombinedRight != null)
-                {
-                    CombinedRight.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Master)
-                        ? Visibility.Visible
-                        : Visibility.Collapsed;
-                }
-                
-                if (CombinedLeft != null)
-                {
-                    CombinedLeft.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Detail)
-                        ? Visibility.Visible
-                        : Visibility.Collapsed;
-                }
 
+            if (CombinedRight != null)
+            {
+                CombinedRight.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Master)
+                    ? Visibility.Visible
+                    : Visibility.Collapsed;
             }
-            catch (Exception e)
+            
+            if (CombinedLeft != null)
             {
-                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+                CombinedLeft.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Detail)
+                    ? Visibility.Visible
+                    : Visibility.Collapsed;
             }
-        }
 
-        private void Splitter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
-        {
-            if (Anchor == DynamicSplitPanelAnchor.Master)
-                SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[1].ActualWidth);
-            else 
-                SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[3].ActualWidth);
-            SetValue(DetailHeightProperty, SecondaryDetail == null ? 0.0F : DetailGrid.RowDefinitions[0].ActualHeight);
-            Changed();
         }
-
-        private void Changed()
+        catch (Exception e)
         {
-            OnChanged?.Invoke(this, new DynamicSplitPanelSettings { View = View, AnchorWidth = AnchorWidth, DetailHeight = DetailHeight });
+            Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
         }
+    }
 
-        public override void OnApplyTemplate()
-        {
-            base.OnApplyTemplate();
+    private void Splitter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
+    {
+        if (Anchor == DynamicSplitPanelAnchor.Master)
+            SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[1].ActualWidth);
+        else 
+            SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[3].ActualWidth);
+        SetValue(DetailHeightProperty, SecondaryDetail == null ? 0.0F : DetailGrid.RowDefinitions[0].ActualHeight);
+        Changed();
+    }
 
-            CheckParts();
+    private void Changed()
+    {
+        OnChanged?.Invoke(this, new DynamicSplitPanelSettings { View = View, AnchorWidth = AnchorWidth, DetailHeight = DetailHeight });
+    }
 
-            ConfigureScreen();
-        }
+    public override void OnApplyTemplate()
+    {
+        base.OnApplyTemplate();
 
-        private void CheckParts()
-        {
-            try
-            {
-                if (Grid == null)
-                    Grid = GetTemplateChild("PART_Grid") as Grid;
+        CheckParts();
 
-                if (DetailGrid == null)
-                    DetailGrid = GetTemplateChild("PART_DetailGrid") as Grid;
+        ConfigureScreen();
+    }
 
-                if (MasterHeader == null)
-                    MasterHeader = GetTemplateChild("PART_MasterHeader") as Label;
+    private void CheckParts()
+    {
+        try
+        {
+            if (Grid == null)
+                Grid = GetTemplateChild("PART_Grid") as Grid;
 
-                if (DetailsHeader == null)
-                    DetailsHeader = GetTemplateChild("PART_DetailHeader") as Label;
+            if (DetailGrid == null)
+                DetailGrid = GetTemplateChild("PART_DetailGrid") as Grid;
 
-                if (Splitter == null)
-                {
-                    Splitter = GetTemplateChild("PART_Splitter") as SfGridSplitter;
-                    if (Splitter != null)
-                    {
-                        Splitter.PreviewMouseUp += Splitter_PreviewMouseUp;
-                        Splitter.TargetUpdated += Splitter_TargetUpdated;
-                    }
-                }
+            if (MasterHeader == null)
+                MasterHeader = GetTemplateChild("PART_MasterHeader") as Label;
 
-                if (DetailSplitter == null)
-                {
-                    DetailSplitter = GetTemplateChild("PART_DetailSplitter") as SfGridSplitter;
-                    if (DetailSplitter != null)
-                        DetailSplitter.PreviewMouseUp += Splitter_PreviewMouseUp;
-                }
+            if (DetailsHeader == null)
+                DetailsHeader = GetTemplateChild("PART_DetailHeader") as Label;
 
-                if (DetailsOnly == null)
+            if (Splitter == null)
+            {
+                Splitter = GetTemplateChild("PART_Splitter") as SfGridSplitter;
+                if (Splitter != null)
                 {
-                    DetailsOnly = GetTemplateChild("PART_DetailsOnly") as Button;
-                    if (DetailsOnly != null)
-                        DetailsOnly.Click += RightClick;
+                    Splitter.PreviewMouseUp += Splitter_PreviewMouseUp;
+                    Splitter.TargetUpdated += Splitter_TargetUpdated;
                 }
+            }
 
-                if (CombinedRight == null)
-                {
-                    CombinedRight = GetTemplateChild("PART_CombinedRight") as Button;
-                    if (CombinedRight != null)
-                        CombinedRight.Click += RightClick;
-                }
+            if (DetailSplitter == null)
+            {
+                DetailSplitter = GetTemplateChild("PART_DetailSplitter") as SfGridSplitter;
+                if (DetailSplitter != null)
+                    DetailSplitter.PreviewMouseUp += Splitter_PreviewMouseUp;
+            }
 
-                if (CombinedLeft == null)
-                {
-                    CombinedLeft = GetTemplateChild("PART_CombinedLeft") as Button;
-                    if (CombinedLeft != null)
-                        CombinedLeft.Click += LeftClick;
-                }
+            if (DetailsOnly == null)
+            {
+                DetailsOnly = GetTemplateChild("PART_DetailsOnly") as Button;
+                if (DetailsOnly != null)
+                    DetailsOnly.Click += RightClick;
+            }
 
-                if (MasterOnly == null)
-                {
-                    MasterOnly = GetTemplateChild("PART_MasterOnly") as Button;
-                    if (MasterOnly != null)
-                        MasterOnly.Click += LeftClick;
-                }
+            if (CombinedRight == null)
+            {
+                CombinedRight = GetTemplateChild("PART_CombinedRight") as Button;
+                if (CombinedRight != null)
+                    CombinedRight.Click += RightClick;
             }
-            catch (Exception e)
+
+            if (CombinedLeft == null)
             {
-                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+                CombinedLeft = GetTemplateChild("PART_CombinedLeft") as Button;
+                if (CombinedLeft != null)
+                    CombinedLeft.Click += LeftClick;
             }
-        }
 
-        private void Splitter_TargetUpdated(object sender, DataTransferEventArgs e)
+            if (MasterOnly == null)
+            {
+                MasterOnly = GetTemplateChild("PART_MasterOnly") as Button;
+                if (MasterOnly != null)
+                    MasterOnly.Click += LeftClick;
+            }
+        }
+        catch (Exception e)
         {
-            //
+            Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
         }
     }
+
+    private void Splitter_TargetUpdated(object sender, DataTransferEventArgs e)
+    {
+        //
+    }
 }

+ 1 - 0
inabox.wpf/DynamicGrid/DynamicEditorForm/EmbeddedDynamicEditorForm.xaml.cs

@@ -240,6 +240,7 @@ namespace InABox.DynamicGrid
 
         private void ClearEvents()
         {
+            // These are events that are set by the grid/host.
             OnEditorValueChanged = null;
             OnFormCustomiseEditor = null;
             OnAfterEditorValueChanged = null;

+ 2 - 0
inabox.wpf/DynamicGrid/DynamicGridCommon.cs

@@ -409,6 +409,8 @@ public delegate void ValidateEvent<T>(DynamicGrid<T> sender, T[] items, List<str
 /// <param name="editor"></param>
 public delegate void OnCustomiseEditor<T>(IDynamicEditorForm sender, T[]? items, DynamicGridColumn column, BaseEditor editor);
 
+public delegate void OnCustomiseEditor(IDynamicEditorForm sender, object[]? items, DynamicGridColumn column, BaseEditor editor);
+
 public delegate void OnLoadEditorButtons<T>(T item, DynamicEditorButtons buttons);
 
 public delegate void OnReconfigureEditors(DynamicEditorGrid sender);

+ 26 - 0
inabox.wpf/DynamicGrid/Grids/DynamicGrid.cs

@@ -50,6 +50,31 @@ public abstract class DynamicGrid<T> : BaseDynamicGrid, IDynamicGridUIComponentP
     public event OnAfterCreateItem? OnAfterCreateItem;
 
     public event EditorValueChangedHandler? OnEditorValueChanged;
+    public event OnAfterEditorValueChanged? OnAfterEditorValueChangedEvent;
+
+    private List<(OnCustomiseEditor, OnCustomiseEditor<T>)> _customiseEditorEvents;
+    event OnCustomiseEditor? IDynamicGrid.OnCustomiseEditor
+    {
+        add
+        {
+            if (value is null) return;
+            void dlg(IDynamicEditorForm sender, T[]? items, DynamicGridColumn column, BaseEditor editor)
+            {
+                value?.Invoke(sender, items, column, editor);
+            }
+            _customiseEditorEvents ??= new();
+            _customiseEditorEvents.Add((value, dlg));
+            OnCustomiseEditor += dlg;
+        }
+        remove
+        {
+            var (_, dlg) = _customiseEditorEvents.FirstOrDefault(x => x.Item1 == value);
+            if(dlg is not null)
+            {
+                OnCustomiseEditor -= dlg;
+            }
+        }
+    }
 
     public event OnCustomiseEditor<T>? OnCustomiseEditor;
 
@@ -620,6 +645,7 @@ public abstract class DynamicGrid<T> : BaseDynamicGrid, IDynamicGridUIComponentP
     {
         var changes = new Dictionary<string, object?>();
         OnAfterEditorValueChanged(grid, items, args, changes);
+        OnAfterEditorValueChangedEvent?.Invoke(grid, args);
         return changes;
     }
 

+ 5 - 0
inabox.wpf/DynamicGrid/Grids/IDynamicGrid.cs

@@ -112,6 +112,9 @@ public interface IDynamicGrid : IBaseDynamicGrid
 
     event OnDefineFilter OnDefineFilter;
 
+    event OnCustomiseEditor? OnCustomiseEditor;
+    event OnAfterEditorValueChanged? OnAfterEditorValueChangedEvent;
+
     DynamicGridColumns MasterColumns { get; }
 
     void AddHiddenColumn(string column);
@@ -125,6 +128,8 @@ public interface IDynamicGrid : IBaseDynamicGrid
 public interface IDynamicGrid<T> : IDynamicGrid
     where T : BaseObject, new()
 {
+    event OnCustomiseEditor<T>? OnCustomiseEditor;
+
     T CreateItem();
 
     T LoadItem(CoreRow row);