Преглед изворни кода

Merge remote-tracking branch 'origin/kenric' into frank

frankvandenbos пре 3 месеци
родитељ
комит
0ab304e9f8

+ 1 - 1
InABox.Avalonia/Images/Images.cs

@@ -4,7 +4,7 @@ using Avalonia.Svg.Skia;
 using InABox.Avalonia.Components;
 using Syncfusion.Pdf.Parsing;
 
-namespace PRS.Avalonia;
+namespace InABox.Avalonia;
 
 public static class Images
 {

+ 7 - 0
InABox.Core/DigitalForms/Layouts/Fields/DFLayoutFieldProperties.cs

@@ -97,6 +97,8 @@ namespace InABox.Core
             SetProperty(nameof(ColourExpression), ColourExpression);
         }
 
+        public abstract object? GetDefaultValue();
+
         private class PropertyLookupGenerator : LookupGenerator<object>
         {
             public PropertyLookupGenerator(object[] items) : base(items)
@@ -230,5 +232,10 @@ namespace InABox.Core
                 yield return pair;
             }
         }
+
+        public sealed override object? GetDefaultValue()
+        {
+            return Default;
+        }
     }
 }

+ 58 - 60
inabox.wpf/DigitalForms/Designer/Controls/DFHeaderControl.cs

@@ -7,77 +7,75 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public class DFHeaderControl : DynamicFormControl<DFLayoutHeader>
 {
-    public class DFHeaderControl : DynamicFormControl<DFLayoutHeader>
+    public FormHeader Header = null!;
+
+    protected override FrameworkElement Create()
     {
-        public FormHeader Header = null!;
+        var style = Control.Style;
 
-        protected override FrameworkElement Create()
+        Header = new FormHeader
+        {
+            Collapsed = Control.Collapsed,
+            HeaderText = Control.Header,
+            FontWeight = style.IsBold ? FontWeights.Bold : FontWeights.Normal,
+            FontStyle = style.IsItalic ? FontStyles.Italic : FontStyles.Normal,
+        };
+        Header.CollapsedChanged += (o, c) =>
+        {
+            FormDesignGrid.CollapseRows(Header, c);
+        };
+        if (FormDesignGrid.IsDesigning)
         {
+            Header.IsEnabled = false;
+        }
 
-            var style = Control.Style;
+        if (style.FontSize > 0)
+        {
+            Header.FontSize = style.FontSize;
+        }
+        if (style.BackgroundColour != System.Drawing.Color.Empty)
+        {
+            Header.Background = new SolidColorBrush(ConvertColour(style.BackgroundColour));
+        }
+        if (style.ForegroundColour != System.Drawing.Color.Empty)
+        {
+            Header.Foreground = new SolidColorBrush(ConvertColour(style.ForegroundColour));
+        }
 
-            Header = new FormHeader
-            {
-                Collapsed = Control.Collapsed,
-                HeaderText = Control.Header,
-                FontWeight = style.IsBold ? FontWeights.Bold : FontWeights.Normal,
-                FontStyle = style.IsItalic ? FontStyles.Italic : FontStyles.Normal,
-            };
-            Header.CollapsedChanged += (o, c) =>
+        if (style.Underline == UnderlineType.Single)
+        {
+            Header.TextDecorations.Add(TextDecorations.Underline);
+        }
+        else if (style.Underline == UnderlineType.Double)
+        {
+            var underline1 = new TextDecoration
             {
-                FormDesignGrid.CollapseRows(Header, c);
+                Pen = new Pen
+                {
+                    Brush = Header.Foreground,
+                }
             };
-            if (FormDesignGrid.IsDesigning)
-            {
-                Header.IsEnabled = false;
-            }
-
-            if (style.FontSize > 0)
-            {
-                Header.FontSize = style.FontSize;
-            }
-            if (style.BackgroundColour != System.Drawing.Color.Empty)
-            {
-                Header.Background = new SolidColorBrush(ConvertColour(style.BackgroundColour));
-            }
-            if (style.ForegroundColour != System.Drawing.Color.Empty)
-            {
-                Header.Foreground = new SolidColorBrush(ConvertColour(style.ForegroundColour));
-            }
-
-            if (style.Underline == UnderlineType.Single)
-            {
-                Header.TextDecorations.Add(TextDecorations.Underline);
-            }
-            else if (style.Underline == UnderlineType.Double)
+            var underline2 = new TextDecoration
             {
-                var underline1 = new TextDecoration
+                Pen = new Pen
                 {
-                    Pen = new Pen
-                    {
-                        Brush = Header.Foreground,
-                    }
-                };
-                var underline2 = new TextDecoration
-                {
-                    Pen = new Pen
-                    {
-                        Brush = Header.Foreground,
-                    },
-                    PenOffset = 2
-                };
-                Header.TextDecorations.Add(underline1);
-                Header.TextDecorations.Add(underline2);
-            }
-
-            return Header;
+                    Brush = Header.Foreground,
+                },
+                PenOffset = 2
+            };
+            Header.TextDecorations.Add(underline1);
+            Header.TextDecorations.Add(underline2);
         }
 
-        private static Color ConvertColour(System.Drawing.Color colour)
-        {
-            return new Color { R = colour.R, G = colour.G, B = colour.B, A = colour.A };
-        }
+        return Header;
+    }
+
+    private static Color ConvertColour(System.Drawing.Color colour)
+    {
+        return new Color { R = colour.R, G = colour.G, B = colour.B, A = colour.A };
     }
 }

+ 70 - 71
inabox.wpf/DigitalForms/Designer/Controls/DFLabelControl.cs

@@ -7,90 +7,89 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public class DFLabelControl : DynamicFormControl<DFLayoutLabel>
 {
-    public class DFLabelControl : DynamicFormControl<DFLayoutLabel>
+    protected override FrameworkElement Create()
     {
-        protected override FrameworkElement Create()
+        var border = new Border
         {
-            var border = new Border
-            {
-                HorizontalAlignment = HorizontalAlignment.Stretch,
-                VerticalAlignment = VerticalAlignment.Stretch
-            };
+            HorizontalAlignment = HorizontalAlignment.Stretch,
+            VerticalAlignment = VerticalAlignment.Stretch
+        };
 
-            var style = Control.Style;
+        var style = Control.Style;
 
-            var textBlock = new TextBlock
-            {
-                Text = Control.Caption,
-                TextWrapping = TextWrapping.WrapWithOverflow,
-                FontWeight = style.IsBold ? FontWeights.Bold : FontWeights.Normal,
-                FontStyle = style.IsItalic ? FontStyles.Italic : FontStyles.Normal,
-                VerticalAlignment = Control.Style.VerticalTextAlignment switch
-                {
-                    DFLayoutAlignment.Start => VerticalAlignment.Top,
-                    DFLayoutAlignment.End => VerticalAlignment.Bottom,
-                    DFLayoutAlignment.Stretch => VerticalAlignment.Stretch,
-                    _ => VerticalAlignment.Center
-                },
-                HorizontalAlignment = HorizontalAlignment.Stretch,
-                TextAlignment = Control.Style.HorizontalTextAlignment switch
-                {
-                    DFLayoutAlignment.Middle => TextAlignment.Center,
-                    DFLayoutAlignment.End => TextAlignment.Right,
-                    DFLayoutAlignment.Stretch => TextAlignment.Justify,
-                    _ => TextAlignment.Left
-                },
-                Margin = new Thickness(5)
-            };
-
-            if(style.FontSize > 0)
-            {
-                textBlock.FontSize = style.FontSize;
-            }
-            if (style.BackgroundColour != System.Drawing.Color.Empty)
+        var textBlock = new TextBlock
+        {
+            Text = Control.Caption,
+            TextWrapping = TextWrapping.WrapWithOverflow,
+            FontWeight = style.IsBold ? FontWeights.Bold : FontWeights.Normal,
+            FontStyle = style.IsItalic ? FontStyles.Italic : FontStyles.Normal,
+            VerticalAlignment = Control.Style.VerticalTextAlignment switch
             {
-                border.Background = new SolidColorBrush(ConvertColour(style.BackgroundColour));
-            }
-            if (style.ForegroundColour != System.Drawing.Color.Empty)
+                DFLayoutAlignment.Start => VerticalAlignment.Top,
+                DFLayoutAlignment.End => VerticalAlignment.Bottom,
+                DFLayoutAlignment.Stretch => VerticalAlignment.Stretch,
+                _ => VerticalAlignment.Center
+            },
+            HorizontalAlignment = HorizontalAlignment.Stretch,
+            TextAlignment = Control.Style.HorizontalTextAlignment switch
             {
-                textBlock.Foreground = new SolidColorBrush(ConvertColour(style.ForegroundColour));
-            }
+                DFLayoutAlignment.Middle => TextAlignment.Center,
+                DFLayoutAlignment.End => TextAlignment.Right,
+                DFLayoutAlignment.Stretch => TextAlignment.Justify,
+                _ => TextAlignment.Left
+            },
+            Margin = new Thickness(5)
+        };
 
-            if (style.Underline == UnderlineType.Single)
-            {
-                textBlock.TextDecorations.Add(TextDecorations.Underline);
-            }
-            else if(style.Underline == UnderlineType.Double)
+        if(style.FontSize > 0)
+        {
+            textBlock.FontSize = style.FontSize;
+        }
+        if (style.BackgroundColour != System.Drawing.Color.Empty)
+        {
+            border.Background = new SolidColorBrush(ConvertColour(style.BackgroundColour));
+        }
+        if (style.ForegroundColour != System.Drawing.Color.Empty)
+        {
+            textBlock.Foreground = new SolidColorBrush(ConvertColour(style.ForegroundColour));
+        }
+
+        if (style.Underline == UnderlineType.Single)
+        {
+            textBlock.TextDecorations.Add(TextDecorations.Underline);
+        }
+        else if(style.Underline == UnderlineType.Double)
+        {
+            var underline1 = new TextDecoration
             {
-                var underline1 = new TextDecoration
+                Pen = new Pen
                 {
-                    Pen = new Pen
-                    {
-                        Brush = textBlock.Foreground,
-                    }
-                };
-                var underline2 = new TextDecoration
+                    Brush = textBlock.Foreground,
+                }
+            };
+            var underline2 = new TextDecoration
+            {
+                Pen = new Pen
                 {
-                    Pen = new Pen
-                    {
-                        Brush = textBlock.Foreground,
-                    },
-                    PenOffset = 2
-                };
-                textBlock.TextDecorations.Add(underline1);
-                textBlock.TextDecorations.Add(underline2);
-            }
+                    Brush = textBlock.Foreground,
+                },
+                PenOffset = 2
+            };
+            textBlock.TextDecorations.Add(underline1);
+            textBlock.TextDecorations.Add(underline2);
+        }
 
-            border.Child = textBlock;
+        border.Child = textBlock;
 
-            return border;
-        }
+        return border;
+    }
 
-        private static Color ConvertColour(System.Drawing.Color colour)
-        {
-            return new Color { R = colour.R, G = colour.G, B = colour.B, A = colour.A };
-        }
+    private static Color ConvertColour(System.Drawing.Color colour)
+    {
+        return new Color { R = colour.R, G = colour.G, B = colour.B, A = colour.A };
     }
 }

+ 79 - 93
inabox.wpf/DigitalForms/Designer/Controls/DynamicFormFieldControl.cs

@@ -8,115 +8,101 @@ using System.Windows;
 using System.Windows.Controls;
 using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public delegate void FieldChangedEvent();
+
+public interface IDynamicFormFieldControl
 {
-    public delegate void FieldChangedEvent();
+    public event FieldChangedEvent? FieldChangedEvent;
+    
+    void Deserialize(DFLoadStorageEntry storage);
+    void Serialize(DFSaveStorageEntry storage);
+
+    public object? GetValue();
+    /// <summary>
+    /// Sets the value in this control.
+    /// </summary>
+    /// <param name="value">The value to set. This will be the return value from a call to <see cref="DFLayoutFieldProperties.ParseValue(object)"/>.</param>
+    public void SetValue(object? value);
+
+    public object? GetEntityValue();
+
+    /// <summary>
+    /// Gets additional data for this field by the specific field name of <paramref name="field"/>.
+    /// </summary>
+    /// <param name="field">A name which specifies what data is requested.</param>
+    /// <returns>The additional data.</returns>
+    public object? GetData(string field);
+
+    /// <summary>
+    /// Check that the data is valid - if it is not, output a message for the user.
+    /// This function gets called when the user completes a form, or edits an already completed form.
+    /// </summary>
+    /// <param name="message">The message to the user.</param>
+    /// <returns><see langword="true"/> if the data is valid.</returns>
+    public bool Validate([NotNullWhen(false)] out string? message);
+}
 
-    public interface IDynamicFormFieldControl
+public abstract class DynamicFormFieldControl<TField, TProperties, TValue, TSerialized> : DynamicFormControl<TField>, IDynamicFormFieldControl
+    where TField : DFLayoutField<TProperties>
+    where TProperties : DFLayoutFieldProperties<TValue, TSerialized>, new()
+{
+    public event FieldChangedEvent? FieldChangedEvent;
+
+    public TField Field { get => Control; set => Control = value; }
+
+    public void Serialize(DFSaveStorageEntry storage)
     {
-        public event FieldChangedEvent? FieldChangedEvent;
-        
-        void Deserialize(DFLoadStorageEntry storage);
-        void Serialize(DFSaveStorageEntry storage);
-
-        public object? GetValue();
-        /// <summary>
-        /// Sets the value in this control.
-        /// </summary>
-        /// <param name="value">The value to set. This will be the return value from a call to <see cref="DFLayoutFieldProperties.ParseValue(object)"/>.</param>
-        public void SetValue(object? value);
-
-        public object? GetEntityValue();
-        public void SetEntityValue(object? value);
-
-        /// <summary>
-        /// Gets additional data for this field by the specific field name of <paramref name="field"/>.
-        /// </summary>
-        /// <param name="field">A name which specifies what data is requested.</param>
-        /// <returns>The additional data.</returns>
-        public object? GetData(string field);
-
-        /// <summary>
-        /// Gets additional data for this field that should be saved into the form data.
-        /// </summary>
-        /// <returns>The additional data.</returns>
-        public Dictionary<string, object?>? GetAdditionalValues();
-
-        /// <summary>
-        /// Check that the data is valid - if it is not, output a message for the user.
-        /// This function gets called when the user completes a form, or edits an already completed form.
-        /// </summary>
-        /// <param name="message">The message to the user.</param>
-        /// <returns><see langword="true"/> if the data is valid.</returns>
-        public bool Validate([NotNullWhen(false)] out string? message);
+        Field.Properties.SerializeValue(storage, GetSerializedValue());
     }
-
-    public abstract class DynamicFormFieldControl<TField, TProperties, TValue, TSerialized> : DynamicFormControl<TField>, IDynamicFormFieldControl
-        where TField : DFLayoutField<TProperties>
-        where TProperties : DFLayoutFieldProperties<TValue, TSerialized>, new()
+    public void Deserialize(DFLoadStorageEntry storage)
     {
-        public event FieldChangedEvent? FieldChangedEvent;
-
-        public TField Field { get => Control; set => Control = value; }
-
-        public void Serialize(DFSaveStorageEntry storage)
-        {
-            Field.Properties.SerializeValue(storage, GetSerializedValue());
-        }
-        public void Deserialize(DFLoadStorageEntry storage)
-        {
-            SetSerializedValue(Field.Properties.DeserializeValue(storage));
-        }
+        SetSerializedValue(Field.Properties.DeserializeValue(storage));
+    }
 
-        protected void ChangeField() => FieldChangedEvent?.Invoke();
+    protected void ChangeField() => FieldChangedEvent?.Invoke();
 
-        /// <summary>
-        /// Checks whether the user has supplied a field - for use with <see cref="Validate(out string?)"/>.
-        /// </summary>
-        /// <returns><see langword="true"/> if the user has not supplied a value.</returns>
-        protected abstract bool IsEmpty();
+    /// <summary>
+    /// Checks whether the user has supplied a field - for use with <see cref="Validate(out string?)"/>.
+    /// </summary>
+    /// <returns><see langword="true"/> if the user has not supplied a value.</returns>
+    protected abstract bool IsEmpty();
 
-        public virtual bool Validate([NotNullWhen(false)] out string? message)
+    public virtual bool Validate([NotNullWhen(false)] out string? message)
+    {
+        if(Field.Properties.Required && IsEmpty())
         {
-            if(Field.Properties.Required && IsEmpty())
-            {
-                message = $"Field [{Field.Name}] is required!";
-                return false;
-            }
-            message = null;
-            return true;
+            message = $"Field [{Field.Name}] is required!";
+            return false;
         }
+        message = null;
+        return true;
+    }
 
-        protected override void AfterSetControl(TField control)
+    protected override void AfterSetControl(TField control)
+    {
+        base.AfterSetControl(control);
+        if (!string.IsNullOrWhiteSpace(control.Properties.Expression)
+            || (!control.Properties.Property.IsNullOrWhiteSpace() && control.Properties.ReadOnlyProperty))
         {
-            base.AfterSetControl(control);
-            if (!string.IsNullOrWhiteSpace(control.Properties.Expression)
-                || (!control.Properties.Property.IsNullOrWhiteSpace() && control.Properties.ReadOnlyProperty))
-            {
-                IsEnabled = false;
-            }
+            IsEnabled = false;
         }
+    }
 
-        public abstract TSerialized GetSerializedValue();
-        public abstract void SetSerializedValue(TSerialized value);
-
-        public abstract TValue GetValue();
-        public abstract void SetValue(TValue? value);
+    public abstract TSerialized GetSerializedValue();
+    public abstract void SetSerializedValue(TSerialized value);
 
-        public virtual object? GetEntityValue() => GetValue();
-        public virtual void SetEntityValue(object? value) => SetValue(CoreUtils.ChangeType<TValue>(value));
+    public abstract TValue GetValue();
+    public abstract void SetValue(TValue? value);
 
-        public virtual object? GetData(string dataField)
-        {
-            return null;
-        }
-        
-        public virtual Dictionary<string, object?>? GetAdditionalValues()
-        {
-            return null;
-        }
+    public virtual object? GetEntityValue() => GetValue();
 
-        object? IDynamicFormFieldControl.GetValue() => GetValue();
-        void IDynamicFormFieldControl.SetValue(object? value) => SetValue(value != null ? (TValue)value : default);
+    public virtual object? GetData(string dataField)
+    {
+        return null;
     }
+
+    object? IDynamicFormFieldControl.GetValue() => GetValue();
+    void IDynamicFormFieldControl.SetValue(object? value) => SetValue(value != null ? (TValue)value : default);
 }

+ 0 - 24
inabox.wpf/DigitalForms/Designer/Controls/Fields/DFLookupControl.cs

@@ -104,34 +104,10 @@ namespace InABox.DynamicGrid
             return (Guid?)Combo.SelectedValue ?? Guid.Empty;
         }
 
-        public override void SetEntityValue(object? value)
-        {
-            if(value is Guid id)
-            {
-                SetValue(id);
-            }
-            else
-            {
-                SetValue(Guid.Empty);
-            }
-        }
-
         public override object? GetData(string dataField)
         {
             return ((KeyValuePair<Guid, ComboItemType>?)Combo.SelectedItem)?.Value.Item2.GetValueOrDefault(dataField);
         }
-        public override Dictionary<string, object?>? GetAdditionalValues()
-        {
-            if (Field.Properties.AdditionalPropertiesList.Count == 0)
-                return null;
-
-            var values = new Dictionary<string, object?>();
-            foreach(var field in Field.Properties.AdditionalPropertiesList)
-            {
-                values[field] = GetData(field);
-            }
-            return values;
-        }
 
         public override Guid GetValue() => ((KeyValuePair<Guid, ComboItemType>?)Combo.SelectedItem)?.Key ?? Guid.Empty;
 

+ 1808 - 1810
inabox.wpf/DigitalForms/Designer/DynamicFormDesignGrid.cs

@@ -27,2369 +27,2367 @@ using Brush = System.Windows.Media.Brush;
 using Color = System.Drawing.Color;
 using Image = System.Windows.Controls.Image;
 using Point = System.Windows.Point;
+using PointI = System.Drawing.Point;
 using Rectangle = System.Windows.Shapes.Rectangle;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public class DynamicFormCreateElementArgs : EventArgs
 {
-    public class DynamicFormCreateElementArgs : EventArgs
+    public DynamicFormCreateElementArgs(DFLayoutElement element, string name)
     {
-        public DynamicFormCreateElementArgs(DFLayoutElement element, string name)
-        {
-            Element = element;
-            Name = name;
-        }
-
-        public DFLayoutElement Element { get; }
-
-        public string Name { get; }
+        Element = element;
+        Name = name;
     }
 
-    public delegate FrameworkElement DynamicFormCreateElementDelegate(object sender, DynamicFormCreateElementArgs e);
-
-    public delegate void DynamicFormAfterDesignDelegate(object sender);
+    public DFLayoutElement Element { get; }
 
-    public delegate void DynamicFormAfterRenderDelegate(DynamicFormDesignGrid sender);
+    public string Name { get; }
+}
 
-    public delegate void DynamicFormOnChangedDelegate(DynamicFormDesignGrid sender, string fieldName);
+public delegate FrameworkElement DynamicFormCreateElementDelegate(object sender, DynamicFormCreateElementArgs e);
 
-    public enum FormMode
-    {
-        /// <summary>
-        /// The form is read-only.
-        /// </summary>
-        ReadOnly,
-        /// <summary>
-        /// Standard option for when the form is being filled in by the associated employee.
-        /// </summary>
-        Filling,
-        /// <summary>
-        /// Standard option for when the form is being previewed - that is, it is acting with placeholder values that will not get saved.
-        /// It is still editable.
-        /// </summary>
-        Preview,
-        /// <summary>
-        /// Once the form has been completed, or the person editing is not the employee the form applies to, then they are put in Editing Mode.<br/>
-        /// This is only possible if <see cref="CanEditCompletedForms"/> is enabled.
-        /// </summary>
-        Editing,
-        /// <summary>
-        /// The form layout is being designed
-        /// </summary>
-        Designing
-    }
+public delegate void DynamicFormAfterDesignDelegate(object sender);
 
-    public class DynamicFormDesignGrid : Grid, IDFRenderer
-    {
+public delegate void DynamicFormAfterRenderDelegate(DynamicFormDesignGrid sender);
 
+public delegate void DynamicFormOnChangedDelegate(DynamicFormDesignGrid sender, string fieldName);
 
-        //private bool _designing;
+public enum FormMode
+{
+    /// <summary>
+    /// The form is read-only.
+    /// </summary>
+    ReadOnly,
+    /// <summary>
+    /// Standard option for when the form is being filled in by the associated employee.
+    /// </summary>
+    Filling,
+    /// <summary>
+    /// Standard option for when the form is being previewed - that is, it is acting with placeholder values that will not get saved.
+    /// It is still editable.
+    /// </summary>
+    Preview,
+    /// <summary>
+    /// Once the form has been completed, or the person editing is not the employee the form applies to, then they are put in Editing Mode.<br/>
+    /// This is only possible if <see cref="CanEditCompletedForms"/> is enabled.
+    /// </summary>
+    Editing,
+    /// <summary>
+    /// The form layout is being designed
+    /// </summary>
+    Designing
+}
+
+public class DynamicFormDesignGrid : Grid, IDFRenderer
+{
+    //private bool _designing;
 
-        public bool GridInitialized { get; private set; } = false;
+    public bool GridInitialized { get; private set; } = false;
 
-        //private bool _readonly;
+    //private bool _readonly;
 
 
-        private readonly SolidColorBrush BackgroundBrush = new(Colors.WhiteSmoke);
-        private readonly SolidColorBrush BorderBrush = new(Colors.Silver);
+    private readonly SolidColorBrush BackgroundBrush = new(Colors.WhiteSmoke);
+    private readonly SolidColorBrush BorderBrush = new(Colors.Silver);
 
-        private readonly Dictionary<Type, IDynamicGrid> elementgrids = new();
+    private readonly Dictionary<Type, IDynamicGrid> elementgrids = new();
 
-        private readonly Dictionary<DFLayoutControl, FrameworkElement> elementmap = new();
-        private readonly Dictionary<DFLayoutControl, Border> borderMap = new();
-        private readonly SolidColorBrush FieldBrush = new(Colors.LightYellow);
+    private readonly Dictionary<DFLayoutControl, FrameworkElement> elementmap = new();
+    private readonly Dictionary<DFLayoutControl, Border> borderMap = new();
+    private readonly SolidColorBrush FieldBrush = new(Colors.LightYellow);
 
 
-        private readonly SolidColorBrush RequiredFieldBrush = new(Colors.Orange);
+    private readonly SolidColorBrush RequiredFieldBrush = new(Colors.Orange);
 
-        public DynamicFormDesignGrid()
-        {
-            PreviewMouseLeftButtonDown += Grid_PreviewMouseLeftButtonDown;
-            PreviewMouseMove += Grid_PreviewMouseMove;
-            PreviewMouseLeftButtonUp += Grid_PreviewMouseLeftButtonUp;
-        }
+    public DynamicFormDesignGrid()
+    {
+        PreviewMouseLeftButtonDown += Grid_PreviewMouseLeftButtonDown;
+        PreviewMouseMove += Grid_PreviewMouseMove;
+        PreviewMouseLeftButtonUp += Grid_PreviewMouseLeftButtonUp;
+    }
 
-        #region Backing Properties
+    #region Backing Properties
 
-        private readonly List<DynamicFormElement> _elements = new();
-        private readonly List<DynamicFormElementAction> _elementActions = new();
-        private bool _showBorders = true;
-        private IDigitalFormDataModel? _datamodel;
-        private DFLayout form = new();
-        private FormMode _mode;
-        private IList<DigitalFormVariable> _variables = new List<DigitalFormVariable>();
-        private bool _isChanged;
-        private bool _changing = false;
+    private readonly List<DynamicFormElement> _elements = new();
+    private readonly List<DynamicFormElementAction> _elementActions = new();
+    private bool _showBorders = true;
+    private IDigitalFormDataModel? _datamodel;
+    private DFLayout form = new();
+    private FormMode _mode;
+    private IList<DigitalFormVariable> _variables = new List<DigitalFormVariable>();
+    private bool _isChanged;
+    private bool _changing = false;
 
-        #endregion
+    #endregion
 
-        #region Public Properties
+    #region Public Properties
 
-        public bool ShowBorders
+    public bool ShowBorders
+    {
+        get => _showBorders || _mode == FormMode.Designing;
+        set
         {
-            get => _showBorders || _mode == FormMode.Designing;
-            set
-            {
-                _showBorders = value;
-                CheckRefresh();
-            }
+            _showBorders = value;
+            CheckRefresh();
         }
+    }
 
-        public IDigitalFormDataModel? DataModel
+    public IDigitalFormDataModel? DataModel
+    {
+        get => _datamodel;
+        set
         {
-            get => _datamodel;
-            set
+            _datamodel = value;
+            if(_datamodel != null)
             {
-                _datamodel = value;
-                if(_datamodel != null)
+                var task = Task.Run(() =>
                 {
-                    var task = Task.Run(() =>
-                    {
-                        var waiting = true;
-                        _datamodel.Load(m => { waiting = false; });
-                        while (waiting) ;
-                    });
-                    task.Wait();
-                }
-
-                CheckRefresh();
+                    var waiting = true;
+                    _datamodel.Load(m => { waiting = false; });
+                    while (waiting) ;
+                });
+                task.Wait();
             }
+
+            CheckRefresh();
         }
+    }
 
-        public DFLayout Form
+    public DFLayout Form
+    {
+        get => form;
+        set
         {
-            get => form;
-            set
-            {
-                form = value;
-                form.Renderer = this;
+            form = value;
+            form.Renderer = this;
 
-                CheckRefresh();
-            }
+            CheckRefresh();
         }
+    }
 
-        public FormMode Mode
+    public FormMode Mode
+    {
+        get => _mode;
+        set
         {
-            get => _mode;
-            set
+            if (_mode != value)
             {
-                if (_mode != value)
+                var oldMode = _mode;
+                if (_mode == FormMode.Designing)
                 {
-                    var oldMode = _mode;
-                    if (_mode == FormMode.Designing)
-                    {
-                        OnAfterDesign?.Invoke(this);
-                    }
+                    OnAfterDesign?.Invoke(this);
+                }
 
-                    _mode = value;
+                _mode = value;
 
-                    CheckRefresh(oldMode != FormMode.Designing);
-                }
+                CheckRefresh(oldMode != FormMode.Designing);
             }
         }
+    }
 
-        public bool IsDesigning { get => _mode == FormMode.Designing; }
-        public bool IsReadOnly { get => _mode == FormMode.ReadOnly; }
-        public bool IsEditing { get => _mode == FormMode.Editing || _mode == FormMode.Filling; }
-        public bool IsChanged => _isChanged;
+    public bool IsDesigning { get => _mode == FormMode.Designing; }
+    public bool IsReadOnly { get => _mode == FormMode.ReadOnly; }
+    public bool IsEditing { get => _mode == FormMode.Editing || _mode == FormMode.Filling; }
+    public bool IsChanged => _isChanged;
 
-        public delegate DigitalFormVariable? CreateVariableHandler(Type fieldType);
-        public delegate bool EditVariableHandler(DigitalFormVariable variable);
+    public delegate DigitalFormVariable? CreateVariableHandler(Type fieldType);
+    public delegate bool EditVariableHandler(DigitalFormVariable variable);
 
-        public event CreateVariableHandler? OnCreateVariable;
-        public event EditVariableHandler? OnEditVariable;
+    public event CreateVariableHandler? OnCreateVariable;
+    public event EditVariableHandler? OnEditVariable;
 
-        public delegate void CustomiseElementContextMenuHandler(ContextMenu menu, DFLayoutElement element);
-        public event CustomiseElementContextMenuHandler? CustomiseElementContextMenu;
+    public delegate void CustomiseElementContextMenuHandler(ContextMenu menu, DFLayoutElement element);
+    public event CustomiseElementContextMenuHandler? CustomiseElementContextMenu;
 
-        public IList<DigitalFormVariable> Variables
+    public IList<DigitalFormVariable> Variables
+    {
+        get => _variables;
+        set
         {
-            get => _variables;
-            set
-            {
-                _variables = value;
-                CheckRefresh();
-            }
+            _variables = value;
+            CheckRefresh();
         }
+    }
 
-        #endregion
+    #endregion
 
-        #region Events
+    #region Events
 
-        public event DynamicFormAfterDesignDelegate? OnAfterDesign;
+    public event DynamicFormAfterDesignDelegate? OnAfterDesign;
 
-        public event DynamicFormCreateElementDelegate? OnCreateElement;
+    public event DynamicFormCreateElementDelegate? OnCreateElement;
 
-        public event DynamicFormAfterRenderDelegate? OnAfterRender;
+    public event DynamicFormAfterRenderDelegate? OnAfterRender;
 
-        public event DynamicFormOnChangedDelegate? OnChanged;
+    public event DynamicFormOnChangedDelegate? OnChanged;
 
-        #endregion
+    #endregion
 
-        #region Rows
+    #region Rows
 
-        class RowData
-        {
-            public string RowHeight { get; set; }
+    class RowData
+    {
+        public string RowHeight { get; set; }
 
-            public RowData(string rowHeight)
-            {
-                RowHeight = rowHeight;
-            }
+        public RowData(string rowHeight)
+        {
+            RowHeight = rowHeight;
         }
+    }
 
-        internal void CollapseRows(FormHeader header, bool collapsed)
-        {
-            var startRow = this.GetRow(header) + this.GetRowSpan(header);
+    internal void CollapseRows(FormHeader header, bool collapsed)
+    {
+        var startRow = this.GetRow(header) + this.GetRowSpan(header);
+
+        var nextRow = elementmap
+            .Where(x => x.Value is DFHeaderControl headerControl && headerControl.Header != header)
+            .Select(x => this.GetRow(x.Value))
+            .Where(x => x >= startRow).DefaultIfEmpty(-1).Min();
 
-            var nextRow = elementmap
-                .Where(x => x.Value is DFHeaderControl headerControl && headerControl.Header != header)
-                .Select(x => this.GetRow(x.Value))
-                .Where(x => x >= startRow).DefaultIfEmpty(-1).Min();
+        if (nextRow == -1)
+        {
+            nextRow = RowDefinitions.Count;
+        }
 
-            if (nextRow == -1)
+        for (int row = startRow; row < nextRow; ++row)
+        {
+            var rowDefinition = RowDefinitions[row];
+            if(rowDefinition.Tag is not RowData rowData)
             {
-                nextRow = RowDefinitions.Count;
+                throw new Exception("Row definition tag is not RowData");
             }
 
-            for (int row = startRow; row < nextRow; ++row)
+            if (collapsed)
             {
-                var rowDefinition = RowDefinitions[row];
-                if(rowDefinition.Tag is not RowData rowData)
-                {
-                    throw new Exception("Row definition tag is not RowData");
-                }
-
-                if (collapsed)
-                {
-                    rowDefinition.Height = new GridLength(0);
-                }
-                else
-                {
-                    rowDefinition.Height = StringToGridLength(rowData.RowHeight);
-                }
+                rowDefinition.Height = new GridLength(0);
+            }
+            else
+            {
+                rowDefinition.Height = StringToGridLength(rowData.RowHeight);
             }
         }
+    }
 
-        #endregion
-
-        #region Elements
+    #endregion
 
-        class DynamicFormElement
-        {
-            public string Caption { get; set; }
-            public Type ElementType { get; set; }
-            public string Category { get; set; }
-            public bool AllowDuplicate { get; set; }
-            public object? Tag { get; set; }
-            public Func<object?, DFLayoutElement>? CreateElement { get; set; }
+    #region Elements
 
-            public bool Visible { get; set; }
+    class DynamicFormElement
+    {
+        public string Caption { get; set; }
+        public Type ElementType { get; set; }
+        public string Category { get; set; }
+        public bool AllowDuplicate { get; set; }
+        public object? Tag { get; set; }
+        public Func<object?, DFLayoutElement>? CreateElement { get; set; }
 
-            public DynamicFormElement(string caption, Type elementType, string category, bool allowDuplicate, bool visible, object? tag, Func<object?, DFLayoutElement>? createElement)
-            {
-                Caption = caption;
-                ElementType = elementType;
-                Category = category;
-                AllowDuplicate = allowDuplicate;
-                Tag = tag;
-                CreateElement = createElement;
-                Visible = visible;
-            }
-        }
+        public bool Visible { get; set; }
 
-        class DynamicFormElementAction
+        public DynamicFormElement(string caption, Type elementType, string category, bool allowDuplicate, bool visible, object? tag, Func<object?, DFLayoutElement>? createElement)
         {
-            public string Caption { get; set; }
+            Caption = caption;
+            ElementType = elementType;
+            Category = category;
+            AllowDuplicate = allowDuplicate;
+            Tag = tag;
+            CreateElement = createElement;
+            Visible = visible;
+        }
+    }
 
-            public Bitmap? Image { get; set; }
+    class DynamicFormElementAction
+    {
+        public string Caption { get; set; }
 
-            public string Category { get; set; }
+        public Bitmap? Image { get; set; }
 
-            public object? Tag { get; set; }
+        public string Category { get; set; }
 
-            public Func<object?, DFLayoutElement?> OnClick { get; set; }
+        public object? Tag { get; set; }
 
-            public DynamicFormElementAction(string caption, Bitmap? image, string category, object? tag, Func<object?, DFLayoutElement> onClick)
-            {
-                Caption = caption;
-                Image = image;
-                Category = category;
-                Tag = tag;
-                OnClick = onClick;
-            }
-        }
+        public Func<object?, DFLayoutElement?> OnClick { get; set; }
 
-        public void ClearElementTypesAndActions()
+        public DynamicFormElementAction(string caption, Bitmap? image, string category, object? tag, Func<object?, DFLayoutElement> onClick)
         {
-            _elements.Clear();
-            _elementActions.Clear();
+            Caption = caption;
+            Image = image;
+            Category = category;
+            Tag = tag;
+            OnClick = onClick;
         }
+    }
 
-        public void AddElementType<TElement>(string caption, string category, bool allowduplicate = false, bool visible = true)
-            where TElement : DFLayoutElement
-        {
-            AddElementType(typeof(TElement), caption, category, allowduplicate, visible: visible);
-        }
-        public void AddElementType<TElement, TTag>(string caption, string category, TTag tag, Func<TTag, TElement> createElement, bool allowduplicate = false, bool visible = true)
-            where TElement : DFLayoutElement
-        {
-            AddElementType(typeof(TElement), caption, category, tag, createElement, allowduplicate, visible: visible);
-        }
+    public void ClearElementTypesAndActions()
+    {
+        _elements.Clear();
+        _elementActions.Clear();
+    }
 
-        public void AddElementType(Type TElement, string caption, string category, bool allowduplicate = false, bool visible = true)
-        {
-            _elements.Add(new DynamicFormElement(caption, TElement, category, allowduplicate, visible, null, null));
-        }
+    public void AddElementType<TElement>(string caption, string category, bool allowduplicate = false, bool visible = true)
+        where TElement : DFLayoutElement
+    {
+        AddElementType(typeof(TElement), caption, category, allowduplicate, visible: visible);
+    }
+    public void AddElementType<TElement, TTag>(string caption, string category, TTag tag, Func<TTag, TElement> createElement, bool allowduplicate = false, bool visible = true)
+        where TElement : DFLayoutElement
+    {
+        AddElementType(typeof(TElement), caption, category, tag, createElement, allowduplicate, visible: visible);
+    }
 
-        public void AddElementType<TTag>(Type TElement, string caption, string category, TTag tag, Func<TTag, DFLayoutElement> createElement, bool allowduplicate = false, bool visible = true)
-        {
-            _elements.Add(new DynamicFormElement(caption, TElement, category, allowduplicate, visible, tag, x => createElement((TTag)x)));
-        }
+    public void AddElementType(Type TElement, string caption, string category, bool allowduplicate = false, bool visible = true)
+    {
+        _elements.Add(new DynamicFormElement(caption, TElement, category, allowduplicate, visible, null, null));
+    }
 
-        public void AddElementAction<TTag>(string caption, Bitmap? image, string category, TTag tag, Func<TTag, DFLayoutElement?> onClick)
-        {
-            _elementActions.Add(new(caption, image, category, tag, x => onClick((TTag)x)));
-        }
+    public void AddElementType<TTag>(Type TElement, string caption, string category, TTag tag, Func<TTag, DFLayoutElement> createElement, bool allowduplicate = false, bool visible = true)
+    {
+        _elements.Add(new DynamicFormElement(caption, TElement, category, allowduplicate, visible, tag, x => createElement((TTag)x)));
+    }
+
+    public void AddElementAction<TTag>(string caption, Bitmap? image, string category, TTag tag, Func<TTag, DFLayoutElement?> onClick)
+    {
+        _elementActions.Add(new(caption, image, category, tag, x => onClick((TTag)x)));
+    }
 
-        internal FrameworkElement? CreateElement(DFLayoutElement element)
+    internal FrameworkElement? CreateElement(DFLayoutElement element)
+    {
+        var elementType = element.GetType();
+        if(_elements.FirstOrDefault(x => x.ElementType == elementType) is DynamicFormElement el)
         {
-            var elementType = element.GetType();
-            if(_elements.FirstOrDefault(x => x.ElementType == elementType) is DynamicFormElement el)
-            {
-                return OnCreateElement?.Invoke(this, new DynamicFormCreateElementArgs(element, el.Caption));
-            }
-            return null;
+            return OnCreateElement?.Invoke(this, new DynamicFormCreateElementArgs(element, el.Caption));
         }
+        return null;
+    }
 
-        #endregion
+    #endregion
 
-        #region Utilities
+    #region Utilities
 
-        private static VerticalAlignment GetVerticalAlignment(DFLayoutAlignment alignment)
-        {
-            return alignment == DFLayoutAlignment.Start
-                ? VerticalAlignment.Top
-                : alignment == DFLayoutAlignment.End
-                    ? VerticalAlignment.Bottom
-                    : alignment == DFLayoutAlignment.Middle
-                        ? VerticalAlignment.Center
-                        : VerticalAlignment.Stretch;
-        }
+    private static VerticalAlignment GetVerticalAlignment(DFLayoutAlignment alignment)
+    {
+        return alignment == DFLayoutAlignment.Start
+            ? VerticalAlignment.Top
+            : alignment == DFLayoutAlignment.End
+                ? VerticalAlignment.Bottom
+                : alignment == DFLayoutAlignment.Middle
+                    ? VerticalAlignment.Center
+                    : VerticalAlignment.Stretch;
+    }
 
-        private static HorizontalAlignment GetHorizontalAlignment(DFLayoutAlignment alignment)
-        {
-            return alignment == DFLayoutAlignment.Start
-                ? HorizontalAlignment.Left
-                : alignment == DFLayoutAlignment.End
-                    ? HorizontalAlignment.Right
-                    : alignment == DFLayoutAlignment.Middle
-                        ? HorizontalAlignment.Center
-                        : HorizontalAlignment.Stretch;
-        }
+    private static HorizontalAlignment GetHorizontalAlignment(DFLayoutAlignment alignment)
+    {
+        return alignment == DFLayoutAlignment.Start
+            ? HorizontalAlignment.Left
+            : alignment == DFLayoutAlignment.End
+                ? HorizontalAlignment.Right
+                : alignment == DFLayoutAlignment.Middle
+                    ? HorizontalAlignment.Center
+                    : HorizontalAlignment.Stretch;
+    }
 
-        private static GridLength StringToGridLength(string length)
-        {
-            if (string.IsNullOrWhiteSpace(length) || string.Equals(length.ToUpper(), "AUTO"))
-                return new GridLength(1, GridUnitType.Auto);
+    private static GridLength StringToGridLength(string length)
+    {
+        if (string.IsNullOrWhiteSpace(length) || string.Equals(length.ToUpper(), "AUTO"))
+            return new GridLength(1, GridUnitType.Auto);
 
-            if (!double.TryParse(length.Replace("*", ""), out var value))
-                value = 1.0F;
-            var type = length.Contains('*') ? GridUnitType.Star : GridUnitType.Pixel;
-            return new GridLength(value, type);
-        }
+        if (!double.TryParse(length.Replace("*", ""), out var value))
+            value = 1.0F;
+        var type = length.Contains('*') ? GridUnitType.Star : GridUnitType.Pixel;
+        return new GridLength(value, type);
+    }
 
-        private static string GridLengthToString(GridLength length)
-        {
-            if (length.IsStar)
-                return length.Value == 1.0F ? "*" : string.Format("{0}*", length.Value);
-            if (length.IsAuto)
-                return "Auto";
-            return length.Value.ToString();
-        }
+    private static string GridLengthToString(GridLength length)
+    {
+        if (length.IsStar)
+            return length.Value == 1.0F ? "*" : string.Format("{0}*", length.Value);
+        if (length.IsAuto)
+            return "Auto";
+        return length.Value.ToString();
+    }
 
-        private static string FormatGridLength(GridLength length, IEnumerable<GridLength> others)
+    private static string FormatGridLength(GridLength length, IEnumerable<GridLength> others)
+    {
+        if (length.IsStar)
         {
-            if (length.IsStar)
-            {
-                double total = 0.0F;
-                foreach (var other in others.Where(x => x.IsStar))
-                    total += other.Value;
-                return string.Format("{0:F0}%", total != 0 ? length.Value * 100.0F / total : 0);
-            }
-
-            if (length.IsAuto)
-                return "Auto";
-            return string.Format("{0}px", length.Value);
+            double total = 0.0F;
+            foreach (var other in others.Where(x => x.IsStar))
+                total += other.Value;
+            return string.Format("{0:F0}%", total != 0 ? length.Value * 100.0F / total : 0);
         }
 
-        private static void AddClick<TTag>(ButtonBase button, TTag tag, Action<TTag> click)
-        {
-            button.Tag = tag;
-            button.Click += (o, e) => click((TTag)(o as FrameworkElement)!.Tag);
-        }
+        if (length.IsAuto)
+            return "Auto";
+        return string.Format("{0}px", length.Value);
+    }
 
-        #endregion
+    private static void AddClick<TTag>(ButtonBase button, TTag tag, Action<TTag> click)
+    {
+        button.Tag = tag;
+        button.Click += (o, e) => click((TTag)(o as FrameworkElement)!.Tag);
+    }
 
-        #region Design Mode
+    #endregion
 
-        #region Selection
+    #region Design Mode
 
-        private class CellSelection : Border
-        {
-            private static readonly System.Windows.Media.Color MainSelectionBorder = Colors.LightBlue;
+    #region Selection
 
-            private int startRow;
-            private int endRow;
-            private int startColumn;
-            private int endColumn;
+    private class CellSelection : Border
+    {
+        private static readonly System.Windows.Media.Color MainSelectionBorder = Colors.LightBlue;
+
+        private int startRow;
+        private int endRow;
+        private int startColumn;
+        private int endColumn;
 
-            public int StartRow
+        public int StartRow
+        {
+            get => startRow;
+            set
             {
-                get => startRow;
-                set
-                {
-                    startRow = value;
-                    UpdatePosition();
-                }
+                startRow = value;
+                UpdatePosition();
             }
+        }
 
-            public int StartColumn
+        public int StartColumn
+        {
+            get => startColumn;
+            set
             {
-                get => startColumn;
-                set
-                {
-                    startColumn = value;
-                    UpdatePosition();
-                }
+                startColumn = value;
+                UpdatePosition();
             }
+        }
 
-            public int EndRow
+        public int EndRow
+        {
+            get => endRow;
+            set
             {
-                get => endRow;
-                set
-                {
-                    endRow = value;
-                    UpdatePosition();
-                }
+                endRow = value;
+                UpdatePosition();
             }
+        }
 
-            public int EndColumn
+        public int EndColumn
+        {
+            get => endColumn;
+            set
             {
-                get => endColumn;
-                set
-                {
-                    endColumn = value;
-                    UpdatePosition();
-                }
+                endColumn = value;
+                UpdatePosition();
             }
+        }
 
-            public bool Selecting = true;
+        public bool Selecting = true;
 
-            public enum SelectionTypes
-            {
-                Main,
-                Secondary,
-                Resizable,
-                ResizeBackground
-            }
+        public enum SelectionTypes
+        {
+            Main,
+            Secondary,
+            Resizable,
+            ResizeBackground
+        }
 
-            public SelectionTypes SelectionType;
+        public SelectionTypes SelectionType;
 
-            public enum Direction
-            {
-                None,
-                Left,
-                Right,
-                Top,
-                Bottom,
-                All
-            }
-            public Direction DragDirection;
-            public bool IsDragging => DragDirection != Direction.None;
+        public enum Direction
+        {
+            None,
+            Left,
+            Right,
+            Top,
+            Bottom,
+            All
+        }
+        public Direction DragDirection;
+        public bool IsDragging => DragDirection != Direction.None;
 
-            public bool IsRowSelection => StartColumn == 0;
-            public bool IsColumnSelection => StartRow == 0;
+        public bool IsRowSelection => StartColumn == 0;
+        public bool IsColumnSelection => StartRow == 0;
 
-            public CellSelection(int startRow, int startColumn, int endRow, int endColumn, SelectionTypes selectionType)
+        public CellSelection(int startRow, int startColumn, int endRow, int endColumn, SelectionTypes selectionType)
+        {
+            SelectionType = selectionType;
+            switch (selectionType)
             {
-                SelectionType = selectionType;
-                switch (selectionType)
-                {
-                    case SelectionTypes.Main:
-                        InitialiseMain();
-                        break;
-                    case SelectionTypes.Secondary:
-                        InitialiseSecondary();
-                        break;
-                    case SelectionTypes.Resizable:
-                        InitializeResizable();
-                        break;
-                    case SelectionTypes.ResizeBackground:
-                        InitializeResizeBackground();
-                        break;
-                }
-
-                this.startRow = startRow;
-                this.startColumn = startColumn;
-                this.endRow = endRow;
-                this.endColumn = endColumn;
-                UpdatePosition();
+                case SelectionTypes.Main:
+                    InitialiseMain();
+                    break;
+                case SelectionTypes.Secondary:
+                    InitialiseSecondary();
+                    break;
+                case SelectionTypes.Resizable:
+                    InitializeResizable();
+                    break;
+                case SelectionTypes.ResizeBackground:
+                    InitializeResizeBackground();
+                    break;
             }
 
-            private void InitialiseMain()
+            this.startRow = startRow;
+            this.startColumn = startColumn;
+            this.endRow = endRow;
+            this.endColumn = endColumn;
+            UpdatePosition();
+        }
+
+        private void InitialiseMain()
+        {
+            var colour = MainSelectionBorder;
+            BorderBrush = new SolidColorBrush(colour);
+            Background = new SolidColorBrush(new System.Windows.Media.Color
             {
-                var colour = MainSelectionBorder;
-                BorderBrush = new SolidColorBrush(colour);
-                Background = new SolidColorBrush(new System.Windows.Media.Color
-                {
-                    A = (byte)(colour.A / 2),
-                    R = colour.R,
-                    G = colour.G,
-                    B = colour.B
-                });
-                SetZIndex(this, 2);
-                BorderThickness = new Thickness(1);
-            }
+                A = (byte)(colour.A / 2),
+                R = colour.R,
+                G = colour.G,
+                B = colour.B
+            });
+            SetZIndex(this, 2);
+            BorderThickness = new Thickness(1);
+        }
 
-            private void InitialiseSecondary()
+        private void InitialiseSecondary()
+        {
+            var rectangle = new Rectangle
             {
-                var rectangle = new Rectangle
-                {
-                    StrokeDashArray = new DoubleCollection { 4, 4 },
-                    Stroke = new SolidColorBrush(Colors.Gray),
-                    StrokeThickness = 1.5
-                };
-                rectangle.SetBinding(Rectangle.WidthProperty, new Binding("ActualWidth") { Source = this });
-                rectangle.SetBinding(Rectangle.HeightProperty, new Binding("ActualHeight") { Source = this });
-                var brush = new VisualBrush { Visual = rectangle };
+                StrokeDashArray = new DoubleCollection { 4, 4 },
+                Stroke = new SolidColorBrush(Colors.Gray),
+                StrokeThickness = 1.5
+            };
+            rectangle.SetBinding(Rectangle.WidthProperty, new Binding("ActualWidth") { Source = this });
+            rectangle.SetBinding(Rectangle.HeightProperty, new Binding("ActualHeight") { Source = this });
+            var brush = new VisualBrush { Visual = rectangle };
 
-                BorderBrush = brush;
-                BorderThickness = new Thickness(1.5);
-                Margin = new Thickness(3);
-            }
+            BorderBrush = brush;
+            BorderThickness = new Thickness(1.5);
+            Margin = new Thickness(3);
+        }
 
-            private void InitializeResizable()
+        private void InitializeResizable()
+        {
+            var rectangle = new Rectangle
             {
-                var rectangle = new Rectangle
-                {
-                    StrokeDashArray = new DoubleCollection { 4, 4 },
-                    Stroke = new SolidColorBrush(Colors.Gray),
-                    StrokeThickness = 3
-                };
-                rectangle.SetBinding(Rectangle.WidthProperty, new Binding("ActualWidth") { Source = this });
-                rectangle.SetBinding(Rectangle.HeightProperty, new Binding("ActualHeight") { Source = this });
-                var brush = new VisualBrush { Visual = rectangle };
+                StrokeDashArray = new DoubleCollection { 4, 4 },
+                Stroke = new SolidColorBrush(Colors.Gray),
+                StrokeThickness = 3
+            };
+            rectangle.SetBinding(Rectangle.WidthProperty, new Binding("ActualWidth") { Source = this });
+            rectangle.SetBinding(Rectangle.HeightProperty, new Binding("ActualHeight") { Source = this });
+            var brush = new VisualBrush { Visual = rectangle };
 
-                BorderBrush = brush;
+            BorderBrush = brush;
 
-                Background = new SolidColorBrush(Colors.Transparent);
-                SetZIndex(this, 2);
-                BorderThickness = new Thickness(10);
+            Background = new SolidColorBrush(Colors.Transparent);
+            SetZIndex(this, 2);
+            BorderThickness = new Thickness(10);
 
-                MouseMove += Resizable_MouseMove;
-            }
+            MouseMove += Resizable_MouseMove;
+        }
 
-            private void InitializeResizeBackground()
+        private void InitializeResizeBackground()
+        {
+            var colour = Colors.WhiteSmoke;
+            Background = new SolidColorBrush(new System.Windows.Media.Color
             {
-                var colour = Colors.WhiteSmoke;
-                Background = new SolidColorBrush(new System.Windows.Media.Color
-                {
-                    A = (byte)(colour.A / 2),
-                    R = colour.R,
-                    G = colour.G,
-                    B = colour.B
-                });
-                SetZIndex(this, 1);
-                BorderThickness = new Thickness(0);
-            }
+                A = (byte)(colour.A / 2),
+                R = colour.R,
+                G = colour.G,
+                B = colour.B
+            });
+            SetZIndex(this, 1);
+            BorderThickness = new Thickness(0);
+        }
 
-            public bool StartDragging(Point position)
-            {
-                if (!IsMouseDirectlyOver) return false;
+        public bool StartDragging(Point position)
+        {
+            if (!IsMouseDirectlyOver) return false;
 
-                var dX = Math.Min(position.X, ActualWidth - position.X);
-                var dY = Math.Min(position.Y, ActualHeight - position.Y);
-                if(Math.Min(dX, dY) < 10)
+            var dX = Math.Min(position.X, ActualWidth - position.X);
+            var dY = Math.Min(position.Y, ActualHeight - position.Y);
+            if(Math.Min(dX, dY) < 10)
+            {
+                if (dX < dY)
                 {
-                    if (dX < dY)
-                    {
-                        DragDirection = position.X < ActualWidth / 2 ? Direction.Left : Direction.Right;
-                    }
-                    else
-                    {
-                        DragDirection = position.Y < ActualHeight / 2 ? Direction.Top : Direction.Bottom;
-                    }
+                    DragDirection = position.X < ActualWidth / 2 ? Direction.Left : Direction.Right;
                 }
                 else
                 {
-                    DragDirection = Direction.All;
-                    return false;
+                    DragDirection = position.Y < ActualHeight / 2 ? Direction.Top : Direction.Bottom;
                 }
-                return true;
             }
-
-            private void Resizable_MouseMove(object sender, MouseEventArgs e)
+            else
             {
-                if (!IsMouseDirectlyOver || IsDragging) return;
+                DragDirection = Direction.All;
+                return false;
+            }
+            return true;
+        }
+
+        private void Resizable_MouseMove(object sender, MouseEventArgs e)
+        {
+            if (!IsMouseDirectlyOver || IsDragging) return;
 
-                var position = e.GetPosition(this);
+            var position = e.GetPosition(this);
 
-                var dX = Math.Min(position.X, ActualWidth - position.X);
-                var dY = Math.Min(position.Y, ActualHeight - position.Y);
-                if (Math.Min(dX, dY) < 10)
+            var dX = Math.Min(position.X, ActualWidth - position.X);
+            var dY = Math.Min(position.Y, ActualHeight - position.Y);
+            if (Math.Min(dX, dY) < 10)
+            {
+                if (dX < dY)
                 {
-                    if (dX < dY)
-                    {
-                        Cursor = Cursors.SizeWE;
-                    }
-                    else
-                    {
-                        Cursor = Cursors.SizeNS;
-                    }
+                    Cursor = Cursors.SizeWE;
                 }
                 else
                 {
-                    Cursor = Cursors.Arrow;
+                    Cursor = Cursors.SizeNS;
                 }
             }
-
-            public void SetEnd(int endRow, int endColumn)
+            else
             {
-                this.endRow = endRow;
-                this.endColumn = endColumn;
-                UpdatePosition();
+                Cursor = Cursors.Arrow;
             }
+        }
 
-            public void SetSize(int startRow, int startColumn, int endRow, int endColumn)
-            {
-                this.startRow = startRow;
-                this.startColumn = startColumn;
-                this.endRow = endRow;
-                this.endColumn = endColumn;
-                UpdatePosition();
-            }
+        public void SetEnd(int endRow, int endColumn)
+        {
+            this.endRow = endRow;
+            this.endColumn = endColumn;
+            UpdatePosition();
+        }
 
-            private void UpdatePosition()
-            {
-                Grid.SetRow(this, Math.Min(startRow, endRow));
-                Grid.SetRowSpan(this, Math.Abs(endRow - startRow) + 1);
+        public void SetSize(int startRow, int startColumn, int endRow, int endColumn)
+        {
+            this.startRow = startRow;
+            this.startColumn = startColumn;
+            this.endRow = endRow;
+            this.endColumn = endColumn;
+            UpdatePosition();
+        }
 
-                Grid.SetColumn(this, Math.Min(startColumn, endColumn));
-                Grid.SetColumnSpan(this, Math.Abs(endColumn - startColumn) + 1);
-            }
+        private void UpdatePosition()
+        {
+            Grid.SetRow(this, Math.Min(startRow, endRow));
+            Grid.SetRowSpan(this, Math.Abs(endRow - startRow) + 1);
 
-            public CellRange ToRange() => new CellRange(StartRow, StartColumn, EndRow, EndColumn);
+            Grid.SetColumn(this, Math.Min(startColumn, endColumn));
+            Grid.SetColumnSpan(this, Math.Abs(endColumn - startColumn) + 1);
         }
 
-        private CellSelection? Selection;
-        private Dictionary<DFLayoutControl, CellSelection> SelectedItemsSelections = new();
+        public CellRange ToRange() => new CellRange(StartRow, StartColumn, EndRow, EndColumn);
+    }
 
-        private class Range
-        {
-            public int Start { get; set; }
+    private CellSelection? Selection;
+    private Dictionary<DFLayoutControl, CellSelection> SelectedItemsSelections = new();
 
-            public int End { get; set; }
+    private class Range
+    {
+        public int Start { get; set; }
 
-            public int Min => Math.Min(Start, End);
-            public int Max => Math.Max(Start, End);
+        public int End { get; set; }
 
-            public Range(int start, int end)
-            {
-                Start = start;
-                End = end;
-            }
+        public int Min => Math.Min(Start, End);
+        public int Max => Math.Max(Start, End);
 
-            public override string ToString() => $"{Start} -> {End}";
+        public Range(int start, int end)
+        {
+            Start = start;
+            End = end;
         }
+
+        public override string ToString() => $"{Start} -> {End}";
+    }
+    
+    private class CellRange
+    {
+        public int StartRow { get; set; }
+        public int StartColumn { get; set; }
+        public int EndRow { get; set; }
+        public int EndColumn { get; set; }
+
+        public int MinRow => Math.Min(StartRow, EndRow);
+        public int MinColumn => Math.Min(StartColumn, EndColumn);
         
-        private class CellRange
+        public int MaxRow => Math.Max(StartRow, EndRow);
+        public int MaxColumn => Math.Max(StartColumn, EndColumn);
+
+        public int RowSpan => Math.Abs(EndRow - StartRow) + 1;
+        public int ColumnSpan => Math.Abs(EndColumn - StartColumn) + 1;
+
+        public CellRange(int row, int column)
         {
-            public int StartRow { get; set; }
-            public int StartColumn { get; set; }
-            public int EndRow { get; set; }
-            public int EndColumn { get; set; }
+            StartRow = row;
+            EndRow = row;
+            StartColumn = column;
+            EndColumn = column;
+        }
 
-            public int MinRow => Math.Min(StartRow, EndRow);
-            public int MinColumn => Math.Min(StartColumn, EndColumn);
-            
-            public int MaxRow => Math.Max(StartRow, EndRow);
-            public int MaxColumn => Math.Max(StartColumn, EndColumn);
+        public CellRange(int startRow, int startColumn, int endRow, int endColumn)
+        {
+            StartRow = startRow;
+            EndRow = endRow;
+            StartColumn = startColumn;
+            EndColumn = endColumn;
+        }
 
-            public int RowSpan => Math.Abs(EndRow - StartRow) + 1;
-            public int ColumnSpan => Math.Abs(EndColumn - StartColumn) + 1;
+        public override string ToString() => $"({StartColumn}, {StartRow}) -> ({EndColumn}, {EndRow})";
+    }
 
-            public CellRange(int row, int column)
-            {
-                StartRow = row;
-                EndRow = row;
-                StartColumn = column;
-                EndColumn = column;
-            }
-
-            public CellRange(int startRow, int startColumn, int endRow, int endColumn)
-            {
-                StartRow = startRow;
-                EndRow = endRow;
-                StartColumn = startColumn;
-                EndColumn = endColumn;
-            }
-
-            public override string ToString() => $"({StartColumn}, {StartRow}) -> ({EndColumn}, {EndRow})";
-        }
-
-        private void ClearSelection()
-        {
-            if (Selection is null) return;
+    private void ClearSelection()
+    {
+        if (Selection is null) return;
 
-            Children.Remove(Selection);
-            Selection = null;
+        Children.Remove(Selection);
+        Selection = null;
 
-            UpdateSecondarySelection();
-        }
+        UpdateSecondarySelection();
+    }
 
-        private void StartSelection(int row, int column)
-        {
-            if (Selection is not null) ClearSelection();
+    private void StartSelection(int row, int column)
+    {
+        if (Selection is not null) ClearSelection();
 
-            Selection = new CellSelection(row, column, row, column, CellSelection.SelectionTypes.Main);
-            Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
-            Children.Add(Selection);
+        Selection = new CellSelection(row, column, row, column, CellSelection.SelectionTypes.Main);
+        Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
+        Children.Add(Selection);
 
-            UpdateSecondarySelection();
-        }
-        private void StartRowSelection(int row)
-        {
-            if (Selection is not null) ClearSelection();
+        UpdateSecondarySelection();
+    }
+    private void StartRowSelection(int row)
+    {
+        if (Selection is not null) ClearSelection();
 
-            Selection = new CellSelection(row, 0, row, ColumnDefinitions.Count - 1, CellSelection.SelectionTypes.Main);
-            Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
-            Children.Add(Selection);
+        Selection = new CellSelection(row, 0, row, ColumnDefinitions.Count - 1, CellSelection.SelectionTypes.Main);
+        Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
+        Children.Add(Selection);
 
-            UpdateSecondarySelection();
-        }
-        private void StartColumnSelection(int column)
-        {
-            if (Selection is not null) ClearSelection();
+        UpdateSecondarySelection();
+    }
+    private void StartColumnSelection(int column)
+    {
+        if (Selection is not null) ClearSelection();
 
-            Selection = new CellSelection(0, column, RowDefinitions.Count - 1, column, CellSelection.SelectionTypes.Main);
-            Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
-            Children.Add(Selection);
+        Selection = new CellSelection(0, column, RowDefinitions.Count - 1, column, CellSelection.SelectionTypes.Main);
+        Selection.MouseRightButtonDown += Selection_MouseRightButtonDown;
+        Children.Add(Selection);
 
-            UpdateSecondarySelection();
-        }
+        UpdateSecondarySelection();
+    }
 
-        private Tuple<int, int> GetRowColIndex(Point point)
+    private Tuple<int, int> GetRowColIndex(Point point)
+    {
+        int rowIdx = -1;
+        int colIdx = -1;
+        for(var c = 0; c < ColumnDefinitions.Count; ++c)
         {
-            int rowIdx = -1;
-            int colIdx = -1;
-            for(var c = 0; c < ColumnDefinitions.Count; ++c)
+            var column = ColumnDefinitions[c];
+            if(point.X >= column.Offset && point.X < column.Offset + column.ActualWidth)
             {
-                var column = ColumnDefinitions[c];
-                if(point.X >= column.Offset && point.X < column.Offset + column.ActualWidth)
-                {
-                    colIdx = c;
-                    break;
-                }
+                colIdx = c;
+                break;
             }
-            for(var r = 0; r < RowDefinitions.Count; ++r)
+        }
+        for(var r = 0; r < RowDefinitions.Count; ++r)
+        {
+            var row = RowDefinitions[r];
+            if(point.Y >= row.Offset && point.Y < row.Offset + row.ActualHeight)
             {
-                var row = RowDefinitions[r];
-                if(point.Y >= row.Offset && point.Y < row.Offset + row.ActualHeight)
-                {
-                    rowIdx = r;
-                    break;
-                }
+                rowIdx = r;
+                break;
             }
-            return new Tuple<int, int>(rowIdx, colIdx);
         }
+        return new Tuple<int, int>(rowIdx, colIdx);
+    }
 
-        private void UpdateSecondarySelection()
+    private void UpdateSecondarySelection()
+    {
+        List<DFLayoutControl> items;
+        if (Selection is null || Selection.IsRowSelection || Selection.IsColumnSelection)
         {
-            List<DFLayoutControl> items;
-            if (Selection is null || Selection.IsRowSelection || Selection.IsColumnSelection)
-            {
-                items = new List<DFLayoutControl>();
-            }
-            else
-            {
-                items = GetSelectedItems().ToList();
-            }
+            items = new List<DFLayoutControl>();
+        }
+        else
+        {
+            items = GetSelectedItems().ToList();
+        }
 
-            var removes = new List<DFLayoutControl>();
-            foreach(var (control, selection) in SelectedItemsSelections)
-            {
-                if (!items.Contains(control))
-                {
-                    removes.Add(control);
-                    Children.Remove(selection);
-                }
-            }
-            foreach(var remove in removes)
+        var removes = new List<DFLayoutControl>();
+        foreach(var (control, selection) in SelectedItemsSelections)
+        {
+            if (!items.Contains(control))
             {
-                SelectedItemsSelections.Remove(remove);
+                removes.Add(control);
+                Children.Remove(selection);
             }
+        }
+        foreach(var remove in removes)
+        {
+            SelectedItemsSelections.Remove(remove);
+        }
 
-            foreach(var item in items)
+        foreach(var item in items)
+        {
+            if (!SelectedItemsSelections.ContainsKey(item))
             {
-                if (!SelectedItemsSelections.ContainsKey(item))
-                {
-                    var selection = new CellSelection(
-                        item.Row, item.Column,
-                        item.Row + item.RowSpan - 1, item.Column + item.ColumnSpan - 1,
-                        CellSelection.SelectionTypes.Secondary);
-                    SelectedItemsSelections.Add(item, selection);
-                    Children.Add(selection);
-                }
+                var selection = new CellSelection(
+                    item.Row, item.Column,
+                    item.Row + item.RowSpan - 1, item.Column + item.ColumnSpan - 1,
+                    CellSelection.SelectionTypes.Secondary);
+                SelectedItemsSelections.Add(item, selection);
+                Children.Add(selection);
             }
         }
+    }
 
-        private void ContinueSelection(int row, int column)
-        {
-            if (Selection is null) return;
+    private void ContinueSelection(int row, int column)
+    {
+        if (Selection is null) return;
 
-            row = Math.Max(row, 1);
-            column = Math.Max(column, 1);
+        row = Math.Max(row, 1);
+        column = Math.Max(column, 1);
 
-            Selection.Selecting = true;
+        Selection.Selecting = true;
 
-            if (Selection.IsRowSelection)
-            {
-                Selection.EndRow = row;
-            }
-            else if (Selection.IsColumnSelection)
-            {
-                Selection.EndColumn = column;
-            }
-            else
-            {
-                Selection.SetEnd(row, column);
-            }
-
-            UpdateSecondarySelection();
+        if (Selection.IsRowSelection)
+        {
+            Selection.EndRow = row;
+        }
+        else if (Selection.IsColumnSelection)
+        {
+            Selection.EndColumn = column;
+        }
+        else
+        {
+            Selection.SetEnd(row, column);
         }
 
-        private void Grid_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        UpdateSecondarySelection();
+    }
+
+    private void Grid_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+    {
+        if (!IsDesigning) return;
+        if(Resizer is not null)
         {
-            if (!IsDesigning) return;
-            if(Resizer is not null)
+            if (Resizer.StartDragging(e.GetPosition(Resizer)))
             {
-                if (Resizer.StartDragging(e.GetPosition(Resizer)))
+                Cursor = Resizer.DragDirection switch
                 {
-                    Cursor = Resizer.DragDirection switch
-                    {
-                        CellSelection.Direction.All => Cursors.SizeAll,
-                        CellSelection.Direction.Left or CellSelection.Direction.Right => Cursors.SizeWE,
-                        _ => Cursors.SizeNS
-                    };
-                    if(Resizer.DragDirection == CellSelection.Direction.All)
-                    {
-                        StartDragPosition = GetRowColIndex(e.GetPosition(this));
-                    }
+                    CellSelection.Direction.All => Cursors.SizeAll,
+                    CellSelection.Direction.Left or CellSelection.Direction.Right => Cursors.SizeWE,
+                    _ => Cursors.SizeNS
+                };
+                if(Resizer.DragDirection == CellSelection.Direction.All)
+                {
+                    StartDragPosition = GetRowColIndex(e.GetPosition(this));
                 }
-                return;
             }
+            return;
+        }
 
-            var (row, column) = GetRowColIndex(e.GetPosition(this));
+        var (row, column) = GetRowColIndex(e.GetPosition(this));
 
-            if(Selection is not null && (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)))
+        if(Selection is not null && (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)))
+        {
+            ContinueSelection(row, column);
+        }
+        else if(Selection is not null && Selection.Selecting)
+        {
+            Selection.Selecting = false;
+        }
+        else
+        {
+            if (column == 0)
             {
-                ContinueSelection(row, column);
+                if (row == 0) return;
+                StartRowSelection(row);
             }
-            else if(Selection is not null && Selection.Selecting)
+            else if (row == 0)
             {
-                Selection.Selecting = false;
+                if (column == 0) return;
+                StartColumnSelection(column);
             }
             else
             {
-                if (column == 0)
-                {
-                    if (row == 0) return;
-                    StartRowSelection(row);
-                }
-                else if (row == 0)
-                {
-                    if (column == 0) return;
-                    StartColumnSelection(column);
-                }
-                else
-                {
-                    StartSelection(row, column);
-                }
+                StartSelection(row, column);
             }
         }
+    }
 
-        private void Grid_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+    private void Grid_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+    {
+        if (!IsDesigning) return;
+
+        var (row, column) = GetRowColIndex(e.GetPosition(this));
+        if (Resizer is not null)
         {
-            if (!IsDesigning) return;
+            ResizeMouseMove(sender, e);
+            return;
+        }
 
-            var (row, column) = GetRowColIndex(e.GetPosition(this));
-            if (Resizer is not null)
-            {
-                ResizeMouseMove(sender, e);
-                return;
-            }
+        if (Selection is null || !Selection.Selecting) return;
+        
+        ContinueSelection(row, column);
+    }
 
-            if (Selection is null || !Selection.Selecting) return;
-            
-            ContinueSelection(row, column);
+    private void Grid_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+    {
+        if(Resizer is not null)
+        {
+            Resizer.DragDirection = CellSelection.Direction.None;
+            Cursor = Cursors.Arrow;
         }
-
-        private void Grid_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        else if (Selection is not null)
         {
-            if(Resizer is not null)
-            {
-                Resizer.DragDirection = CellSelection.Direction.None;
-                Cursor = Cursors.Arrow;
-            }
-            else if (Selection is not null)
-            {
-                Selection.Selecting = false;
-            }
+            Selection.Selecting = false;
         }
+    }
 
-        private IEnumerable<Tuple<DFLayoutControl, FrameworkElement>> GetSelectedMaps(CellRange? range = null)
-        {
-            range ??= Selection?.ToRange();
-            if (range is null) yield break;
+    private IEnumerable<Tuple<DFLayoutControl, FrameworkElement>> GetSelectedMaps(CellRange? range = null)
+    {
+        range ??= Selection?.ToRange();
+        if (range is null) yield break;
 
-            var minRow = Math.Min(range.StartRow, range.EndRow);
-            var maxRow = Math.Max(range.StartRow, range.EndRow);
-            var minCol = Math.Min(range.StartColumn, range.EndColumn);
-            var maxCol = Math.Max(range.StartColumn, range.EndColumn);
+        var minRow = Math.Min(range.StartRow, range.EndRow);
+        var maxRow = Math.Max(range.StartRow, range.EndRow);
+        var minCol = Math.Min(range.StartColumn, range.EndColumn);
+        var maxCol = Math.Max(range.StartColumn, range.EndColumn);
 
-            foreach(var (control, element) in elementmap)
+        foreach(var (control, element) in elementmap)
+        {
+            if(control.Row <= maxRow && control.Row + control.RowSpan - 1 >= minRow
+                && control.Column <= maxCol && control.Column + control.ColumnSpan - 1 >= minCol)
             {
-                if(control.Row <= maxRow && control.Row + control.RowSpan - 1 >= minRow
-                    && control.Column <= maxCol && control.Column + control.ColumnSpan - 1 >= minCol)
-                {
-                    yield return new(control, element);
-                }
+                yield return new(control, element);
             }
         }
+    }
 
-        private IEnumerable<DFLayoutControl> GetSelectedItems(CellRange? range = null) => GetSelectedMaps(range).Select(x => x.Item1);
+    private IEnumerable<DFLayoutControl> GetSelectedItems(CellRange? range = null) => GetSelectedMaps(range).Select(x => x.Item1);
 
-        private void PopulateSelectionMenu(ContextMenu menu)
-        {
-            if (Selection is null) return;
+    private void PopulateSelectionMenu(ContextMenu menu)
+    {
+        if (Selection is null) return;
 
-            if (Selection.IsRowSelection)
+        if (Selection.IsRowSelection)
+        {
+            var nRows = Math.Abs(Selection.EndRow - Selection.StartRow) + 1;
+            if (nRows == 1)
             {
-                var nRows = Math.Abs(Selection.EndRow - Selection.StartRow) + 1;
-                if (nRows == 1)
-                {
-                    PopulateRowMenu(menu, Selection.StartRow - 1);
-                }
-                else
-                {
-                    menu.AddItem(nRows == 1 ? "Delete Row" : "Delete Rows", null, new Range(Selection.StartRow - 1, Selection.EndRow - 1), DeleteRows);
-                }
+                PopulateRowMenu(menu, Selection.StartRow - 1);
             }
-            else if (Selection.IsColumnSelection)
+            else
             {
-                var nColumns = Math.Abs(Selection.EndColumn - Selection.StartColumn) + 1;
-                if (nColumns == 1)
-                {
-                    PopulateColumnMenu(menu, Selection.StartColumn - 1);
-                }
-                else
-                {
-                    menu.AddItem(nColumns == 1 ? "Delete Column" : "Delete Columns", null, new Range(Selection.StartColumn - 1, Selection.EndColumn - 1), DeleteColumns);
-                }
+                menu.AddItem(nRows == 1 ? "Delete Row" : "Delete Rows", null, new Range(Selection.StartRow - 1, Selection.EndRow - 1), DeleteRows);
+            }
+        }
+        else if (Selection.IsColumnSelection)
+        {
+            var nColumns = Math.Abs(Selection.EndColumn - Selection.StartColumn) + 1;
+            if (nColumns == 1)
+            {
+                PopulateColumnMenu(menu, Selection.StartColumn - 1);
             }
             else
             {
-                var selectedItems = GetSelectedItems().ToList();
-                if (selectedItems.Count == 0)
-                {
-                    PopulateEmptyCellMenu(menu, Selection.ToRange());
-                }
-                if (selectedItems.Count == 1)
-                {
-                    var item = selectedItems.First();
+                menu.AddItem(nColumns == 1 ? "Delete Column" : "Delete Columns", null, new Range(Selection.StartColumn - 1, Selection.EndColumn - 1), DeleteColumns);
+            }
+        }
+        else
+        {
+            var selectedItems = GetSelectedItems().ToList();
+            if (selectedItems.Count == 0)
+            {
+                PopulateEmptyCellMenu(menu, Selection.ToRange());
+            }
+            if (selectedItems.Count == 1)
+            {
+                var item = selectedItems.First();
 
-                    PopulateElementContextMenu(menu, item);
-                }
-                else if (selectedItems.Count > 1)
-                {
-                    menu.AddItem("Delete Items", null, selectedItems, DeleteElements);
-                }
+                PopulateElementContextMenu(menu, item);
+            }
+            else if (selectedItems.Count > 1)
+            {
+                menu.AddItem("Delete Items", null, selectedItems, DeleteElements);
             }
         }
+    }
 
-        private void Selection_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
-        {
-            if (!IsDesigning || Selection is null) return;
+    private void Selection_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+    {
+        if (!IsDesigning || Selection is null) return;
 
-            var menu = new ContextMenu();
+        var menu = new ContextMenu();
 
-            PopulateSelectionMenu(menu);
+        PopulateSelectionMenu(menu);
 
-            if(menu.Items.Count == 0)
-            {
-                menu.AddItem("No actions available", null, null, false);
-            }
-            menu.IsOpen = true;
+        if(menu.Items.Count == 0)
+        {
+            menu.AddItem("No actions available", null, null, false);
         }
+        menu.IsOpen = true;
+    }
 
-        #endregion
+    #endregion
 
-        #region Resizing
+    #region Resizing
 
-        private CellSelection? Resizer;
-        private Tuple<int, int> StartDragPosition;
+    private CellSelection? Resizer;
+    private Tuple<int, int> StartDragPosition;
 
-        private CellSelection? TopResizeBackground;
-        private CellSelection? LeftResizeBackground;
-        private CellSelection? RightResizeBackground;
-        private CellSelection? BottomResizeBackground;
+    private CellSelection? TopResizeBackground;
+    private CellSelection? LeftResizeBackground;
+    private CellSelection? RightResizeBackground;
+    private CellSelection? BottomResizeBackground;
 
-        private DFLayoutControl? ResizingControl;
+    private DFLayoutControl? ResizingControl;
 
-        private CellSelection GetResizeBackground(ref CellSelection? background)
+    private CellSelection GetResizeBackground(ref CellSelection? background)
+    {
+        if(background is null)
         {
-            if(background is null)
-            {
-                background = new CellSelection(0, 0, 0, 0, CellSelection.SelectionTypes.ResizeBackground);
-                background.PreviewMouseDown += ResizerBackground_PreviewMouseDown;
-                Children.Add(background);
-            }
-            return background;
+            background = new CellSelection(0, 0, 0, 0, CellSelection.SelectionTypes.ResizeBackground);
+            background.PreviewMouseDown += ResizerBackground_PreviewMouseDown;
+            Children.Add(background);
         }
-        private void ClearResizeBackground(ref CellSelection? background)
+        return background;
+    }
+    private void ClearResizeBackground(ref CellSelection? background)
+    {
+        if(background is not null)
         {
-            if(background is not null)
-            {
-                Children.Remove(background);
-                background = null;
-            }
+            Children.Remove(background);
+            background = null;
         }
+    }
 
-        private void ResizerBackground_PreviewMouseDown(object sender, MouseButtonEventArgs e)
-        {
-            FinishResize();
-        }
+    private void ResizerBackground_PreviewMouseDown(object sender, MouseButtonEventArgs e)
+    {
+        FinishResize();
+    }
 
-        private void SetResizerBackgroundSize(CellSelection background, int startRow, int startColumn, int endRow, int endColumn)
-        {
-            background.SetSize(startRow, startColumn, endRow, endColumn);
-            background.Visibility = endColumn >= startColumn && endRow >= startRow ? Visibility.Visible : Visibility.Collapsed;
-        }
+    private void SetResizerBackgroundSize(CellSelection background, int startRow, int startColumn, int endRow, int endColumn)
+    {
+        background.SetSize(startRow, startColumn, endRow, endColumn);
+        background.Visibility = endColumn >= startColumn && endRow >= startRow ? Visibility.Visible : Visibility.Collapsed;
+    }
 
-        private void UpdateResizer(CellRange newSize)
-        {
-            if (Resizer is null) return;
+    private void UpdateResizer(CellRange newSize)
+    {
+        if (Resizer is null) return;
 
-            Resizer.StartRow = newSize.StartRow;
-            Resizer.StartColumn = newSize.StartColumn;
-            Resizer.EndRow = newSize.EndRow;
-            Resizer.EndColumn = newSize.EndColumn;
+        Resizer.StartRow = newSize.StartRow;
+        Resizer.StartColumn = newSize.StartColumn;
+        Resizer.EndRow = newSize.EndRow;
+        Resizer.EndColumn = newSize.EndColumn;
 
-            SetResizerBackgroundSize(GetResizeBackground(ref LeftResizeBackground), 0, 0, RowDefinitions.Count - 1, newSize.MinColumn - 1);
-            SetResizerBackgroundSize(GetResizeBackground(ref RightResizeBackground), 0, newSize.MaxColumn + 1, RowDefinitions.Count - 1, ColumnDefinitions.Count - 1);
-            SetResizerBackgroundSize(GetResizeBackground(ref TopResizeBackground), 0, newSize.MinColumn, newSize.MinRow - 1, newSize.MaxColumn);
-            SetResizerBackgroundSize(GetResizeBackground(ref BottomResizeBackground), newSize.MaxRow + 1, newSize.MinColumn, RowDefinitions.Count - 1, newSize.MaxColumn);
-        }
+        SetResizerBackgroundSize(GetResizeBackground(ref LeftResizeBackground), 0, 0, RowDefinitions.Count - 1, newSize.MinColumn - 1);
+        SetResizerBackgroundSize(GetResizeBackground(ref RightResizeBackground), 0, newSize.MaxColumn + 1, RowDefinitions.Count - 1, ColumnDefinitions.Count - 1);
+        SetResizerBackgroundSize(GetResizeBackground(ref TopResizeBackground), 0, newSize.MinColumn, newSize.MinRow - 1, newSize.MaxColumn);
+        SetResizerBackgroundSize(GetResizeBackground(ref BottomResizeBackground), newSize.MaxRow + 1, newSize.MinColumn, RowDefinitions.Count - 1, newSize.MaxColumn);
+    }
 
-        private void ResizeMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
-        {
-            if (Resizer is null) return;
-            if (!Resizer.IsDragging) return;
+    private void ResizeMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+    {
+        if (Resizer is null) return;
+        if (!Resizer.IsDragging) return;
 
-            var (row, column) = GetRowColIndex(e.GetPosition(this));
+        var (row, column) = GetRowColIndex(e.GetPosition(this));
 
-            var newSize = Resizer.ToRange();
+        var newSize = Resizer.ToRange();
 
-            switch (Resizer.DragDirection)
-            {
-                case CellSelection.Direction.Right:
-                    var startColumn = newSize.MinColumn;
-                    for (int c = column; c >= startColumn; --c)
+        switch (Resizer.DragDirection)
+        {
+            case CellSelection.Direction.Right:
+                var startColumn = newSize.MinColumn;
+                for (int c = column; c >= startColumn; --c)
+                {
+                    newSize.StartColumn = startColumn;
+                    newSize.EndColumn = Math.Max(c, startColumn);
+                    if (ResizeAllowed(newSize))
                     {
-                        newSize.StartColumn = startColumn;
-                        newSize.EndColumn = Math.Max(c, startColumn);
-                        if (ResizeAllowed(newSize))
-                        {
-                            break;
-                        }
+                        break;
                     }
-                    break;
-                case CellSelection.Direction.Left:
-                    var endColumn = newSize.MaxColumn;
-                    for (int c = column; c <= endColumn; ++c)
+                }
+                break;
+            case CellSelection.Direction.Left:
+                var endColumn = newSize.MaxColumn;
+                for (int c = column; c <= endColumn; ++c)
+                {
+                    newSize.StartColumn = Math.Min(c, endColumn);
+                    newSize.EndColumn = endColumn;
+                    if (ResizeAllowed(newSize))
                     {
-                        newSize.StartColumn = Math.Min(c, endColumn);
-                        newSize.EndColumn = endColumn;
-                        if (ResizeAllowed(newSize))
-                        {
-                            break;
-                        }
+                        break;
                     }
-                    break;
-                case CellSelection.Direction.Bottom:
-                    var startRow = newSize.MinRow;
-                    for (int r = row; r >= startRow; --r)
+                }
+                break;
+            case CellSelection.Direction.Bottom:
+                var startRow = newSize.MinRow;
+                for (int r = row; r >= startRow; --r)
+                {
+                    newSize.StartRow = startRow;
+                    newSize.EndRow = Math.Max(r, startRow);
+                    if (ResizeAllowed(newSize))
                     {
-                        newSize.StartRow = startRow;
-                        newSize.EndRow = Math.Max(r, startRow);
-                        if (ResizeAllowed(newSize))
-                        {
-                            break;
-                        }
+                        break;
                     }
-                    break;
-                case CellSelection.Direction.Top:
-                    var endRow = newSize.MaxRow;
-                    for (int r = row; r <= endRow; ++r)
+                }
+                break;
+            case CellSelection.Direction.Top:
+                var endRow = newSize.MaxRow;
+                for (int r = row; r <= endRow; ++r)
+                {
+                    newSize.StartRow = Math.Min(r, endRow);
+                    newSize.EndRow = endRow;
+                    if (ResizeAllowed(newSize))
                     {
-                        newSize.StartRow = Math.Min(r, endRow);
-                        newSize.EndRow = endRow;
-                        if (ResizeAllowed(newSize))
-                        {
-                            break;
-                        }
+                        break;
                     }
-                    break;
-                case CellSelection.Direction.None:
-                    return;
-            }
-            UpdateResizer(newSize);
+                }
+                break;
+            case CellSelection.Direction.None:
+                return;
         }
+        UpdateResizer(newSize);
+    }
 
-        private bool ResizeAllowed(CellRange range)
-        {
-            var items = GetSelectedItems(range).ToList();
-            if (items.Count > 1) return false;
-            return items.Count == 0 ||
-                (items.Count == 1 && items.First() == ResizingControl);
-        }
+    private bool ResizeAllowed(CellRange range)
+    {
+        var items = GetSelectedItems(range).ToList();
+        if (items.Count > 1) return false;
+        return items.Count == 0 ||
+            (items.Count == 1 && items.First() == ResizingControl);
+    }
 
-        private void ClearResize()
-        {
-            if (Resizer is null) return;
+    private void ClearResize()
+    {
+        if (Resizer is null) return;
 
-            Children.Remove(Resizer);
-            Resizer = null;
-            ResizingControl = null;
+        Children.Remove(Resizer);
+        Resizer = null;
+        ResizingControl = null;
 
-            ClearResizeBackground(ref LeftResizeBackground);
-            ClearResizeBackground(ref RightResizeBackground);
-            ClearResizeBackground(ref TopResizeBackground);
-            ClearResizeBackground(ref BottomResizeBackground);
-        }
+        ClearResizeBackground(ref LeftResizeBackground);
+        ClearResizeBackground(ref RightResizeBackground);
+        ClearResizeBackground(ref TopResizeBackground);
+        ClearResizeBackground(ref BottomResizeBackground);
+    }
+
+    private void FinishResize()
+    {
+        if (Resizer is null) return;
 
-        private void FinishResize()
+        var range = Resizer.ToRange();
+
+        if(ResizingControl is not null)
         {
-            if (Resizer is null) return;
+            ResizingControl.Row = range.MinRow;
+            ResizingControl.Column = range.MinColumn;
+            ResizingControl.RowSpan = range.RowSpan;
+            ResizingControl.ColumnSpan = range.ColumnSpan;
+        }
+
+        ClearResize();
+        Render();
+    }
 
-            var range = Resizer.ToRange();
+    private void ResizeItem(DFLayoutControl control)
+    {
+        ClearSelection();
+        ClearResize();
 
-            if(ResizingControl is not null)
-            {
-                ResizingControl.Row = range.MinRow;
-                ResizingControl.Column = range.MinColumn;
-                ResizingControl.RowSpan = range.RowSpan;
-                ResizingControl.ColumnSpan = range.ColumnSpan;
-            }
+        Resizer = new CellSelection(
+            control.Row, control.Column,
+            control.Row + control.RowSpan - 1, control.Column + control.ColumnSpan - 1,
+            CellSelection.SelectionTypes.Resizable);
+        ResizingControl = control;
+        Children.Add(Resizer);
 
-            ClearResize();
-            Render();
-        }
+        UpdateResizer(Resizer.ToRange());
+    }
 
-        private void ResizeItem(DFLayoutControl control)
+    public void HandleKeyDown(KeyEventArgs e)
+    {
+        if (Resizer is null) return;
+        if(e.Key == Key.Enter)
+        {
+            FinishResize();
+        }
+        else if(e.Key == Key.Escape)
         {
-            ClearSelection();
             ClearResize();
+        }
+    }
 
-            Resizer = new CellSelection(
-                control.Row, control.Column,
-                control.Row + control.RowSpan - 1, control.Column + control.ColumnSpan - 1,
-                CellSelection.SelectionTypes.Resizable);
-            ResizingControl = control;
-            Children.Add(Resizer);
+    #endregion
 
-            UpdateResizer(Resizer.ToRange());
-        }
+    #region Rows
 
-        public void HandleKeyDown(KeyEventArgs e)
-        {
-            if (Resizer is null) return;
-            if(e.Key == Key.Enter)
-            {
-                FinishResize();
-            }
-            else if(e.Key == Key.Escape)
-            {
-                ClearResize();
-            }
-        }
+    private void ShiftDown(int row)
+    {
+        foreach (var element in form.Elements)
+            if (element.Row > row)
+                element.Row++;
+            else if (element.Row + element.RowSpan - 1 > row)
+                element.RowSpan++;
+    }
 
-        #endregion
+    private void AddRowBeforeClick(int row)
+    {
+        var length = new GridLength(1.0F, GridUnitType.Auto);
+        var result = GridLengthToString(length);
+        if (form.RowHeights.Count == 0)
+            form.RowHeights.Add(result);
+        else
+            form.RowHeights.Insert(row, result);
+        ShiftDown(row);
+        Render();
+    }
 
-        #region Rows
+    private void AddRowAfterClick(int row)
+    {
+        var length = new GridLength(1.0F, GridUnitType.Auto);
+        var result = GridLengthToString(length);
+        if (row == form.RowHeights.Count - 1)
+            form.RowHeights.Add(result);
+        else
+            form.RowHeights.Insert(row + 1, result);
+        ShiftDown(row + 1);
+        Render();
+    }
 
-        private void ShiftDown(int row)
-        {
-            foreach (var element in form.Elements)
-                if (element.Row > row)
-                    element.Row++;
-                else if (element.Row + element.RowSpan - 1 > row)
-                    element.RowSpan++;
-        }
+    private void SplitRow(int row)
+    {
+        foreach (var element in form.Elements)
+            if (element.Row > row)
+                element.Row++;
+            else if (element.Row == row)
+                element.RowSpan++;
+            else if (element.Row + element.RowSpan - 1 >= row)
+                element.RowSpan++;
+    }
 
-        private void AddRowBeforeClick(int row)
-        {
-            var length = new GridLength(1.0F, GridUnitType.Auto);
-            var result = GridLengthToString(length);
-            if (form.RowHeights.Count == 0)
-                form.RowHeights.Add(result);
-            else
-                form.RowHeights.Insert(row, result);
-            ShiftDown(row);
-            Render();
-        }
+    private void SplitRowClick(int row)
+    {
+        var height = StringToGridLength(form.RowHeights[row]);
+        var newHeight = height.GridUnitType == GridUnitType.Auto
+            ? height
+            : new GridLength(height.Value / 2, height.GridUnitType);
+        var result = GridLengthToString(newHeight);
+        form.RowHeights[row] = result;
+        
+        if (row == form.RowHeights.Count - 1)
+            form.RowHeights.Add(result);
+        else
+            form.RowHeights.Insert(row + 1, result);
+        SplitRow(row + 1);
+        Render();
+    }
+
+    private void RowPropertiesClick(int row)
+    {
+        var length = StringToGridLength(form.RowHeights[row]);
 
-        private void AddRowAfterClick(int row)
+        var editor = new DynamicFormDesignLength(length);
+        if (editor.ShowDialog() == true)
         {
-            var length = new GridLength(1.0F, GridUnitType.Auto);
-            var result = GridLengthToString(length);
-            if (row == form.RowHeights.Count - 1)
-                form.RowHeights.Add(result);
-            else
-                form.RowHeights.Insert(row + 1, result);
-            ShiftDown(row + 1);
+            form.RowHeights[row] = GridLengthToString(editor.GridLength);
             Render();
         }
+    }
+
+    private void ShiftUp(int row)
+    {
+        var deletes = new List<DFLayoutControl>();
+        foreach (var element in form.Elements)
+            if (element.Row > row)
+                element.Row--;
+            else if (element.Row == row && element.RowSpan <= 1)
+                deletes.Add(element);
+            else if (element.Row + element.RowSpan - 1 >= row)
+                element.RowSpan--;
+        foreach (var delete in deletes)
+            form.Elements.Remove(delete);
+    }
 
-        private void SplitRow(int row)
+    private void DeleteRows(Range rows)
+    {
+        for(var row = rows.Max; row >= rows.Min; --row)
         {
-            foreach (var element in form.Elements)
-                if (element.Row > row)
-                    element.Row++;
-                else if (element.Row == row)
-                    element.RowSpan++;
-                else if (element.Row + element.RowSpan - 1 >= row)
-                    element.RowSpan++;
+            form.RowHeights.RemoveAt(row);
+            ShiftUp(row + 1);
         }
-
-        private void SplitRowClick(int row)
+        if(form.RowHeights.Count == 0)
         {
-            var height = StringToGridLength(form.RowHeights[row]);
-            var newHeight = height.GridUnitType == GridUnitType.Auto
-                ? height
-                : new GridLength(height.Value / 2, height.GridUnitType);
-            var result = GridLengthToString(newHeight);
-            form.RowHeights[row] = result;
-            
-            if (row == form.RowHeights.Count - 1)
-                form.RowHeights.Add(result);
-            else
-                form.RowHeights.Insert(row + 1, result);
-            SplitRow(row + 1);
-            Render();
+            form.RowHeights.Add("Auto");
         }
+        Render();
+    }
 
-        private void RowPropertiesClick(int row)
-        {
-            var length = StringToGridLength(form.RowHeights[row]);
+    private void PopulateRowMenu(ContextMenu menu, int row)
+    {
+        menu.AddItem("Add Row Before", null, row, AddRowBeforeClick);
+        menu.AddItem("Add Row After", null, row, AddRowAfterClick);
+        menu.AddSeparator();
+        menu.AddItem("Split Row", null, row, SplitRowClick);
 
-            var editor = new DynamicFormDesignLength(length);
-            if (editor.ShowDialog() == true)
-            {
-                form.RowHeights[row] = GridLengthToString(editor.GridLength);
-                Render();
-            }
-        }
+        var propertiesSeparator = menu.AddSeparator();
+        var propertiesMenu = menu.AddItem("Row Properties", null, row, RowPropertiesClick);
 
-        private void ShiftUp(int row)
+        menu.AddSeparator();
+        menu.AddItem("Delete Row", null, new Range(row, row), DeleteRows);
+        menu.Opened += (o, e) =>
         {
-            var deletes = new List<DFLayoutControl>();
-            foreach (var element in form.Elements)
-                if (element.Row > row)
-                    element.Row--;
-                else if (element.Row == row && element.RowSpan <= 1)
-                    deletes.Add(element);
-                else if (element.Row + element.RowSpan - 1 >= row)
-                    element.RowSpan--;
-            foreach (var delete in deletes)
-                form.Elements.Remove(delete);
-        }
+            propertiesSeparator.Visibility = form.RowHeights.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
+            propertiesMenu.Visibility = form.RowHeights.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
+        };
+    }
 
-        private void DeleteRows(Range rows)
-        {
-            for(var row = rows.Max; row >= rows.Min; --row)
-            {
-                form.RowHeights.RemoveAt(row);
-                ShiftUp(row + 1);
-            }
-            if(form.RowHeights.Count == 0)
-            {
-                form.RowHeights.Add("Auto");
-            }
-            Render();
-        }
+    private ContextMenu CreateRowMenu(Button button, int row)
+    {
+        var result = new ContextMenu();
+        PopulateRowMenu(result, row);
+        button.SetValue(ContextMenuProperty, result);
+        return result;
+    }
 
-        private void PopulateRowMenu(ContextMenu menu, int row)
-        {
-            menu.AddItem("Add Row Before", null, row, AddRowBeforeClick);
-            menu.AddItem("Add Row After", null, row, AddRowAfterClick);
-            menu.AddSeparator();
-            menu.AddItem("Split Row", null, row, SplitRowClick);
+    #endregion
 
-            var propertiesSeparator = menu.AddSeparator();
-            var propertiesMenu = menu.AddItem("Row Properties", null, row, RowPropertiesClick);
+    #region Columns
 
-            menu.AddSeparator();
-            menu.AddItem("Delete Row", null, new Range(row, row), DeleteRows);
-            menu.Opened += (o, e) =>
-            {
-                propertiesSeparator.Visibility = form.RowHeights.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
-                propertiesMenu.Visibility = form.RowHeights.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
-            };
-        }
+    private void ShiftRight(int column)
+    {
+        foreach (var element in form.Elements)
+            if (element.Column > column)
+                element.Column++;
+            else if (element.Column + element.ColumnSpan - 1 > column)
+                element.ColumnSpan++;
+    }
 
-        private ContextMenu CreateRowMenu(Button button, int row)
-        {
-            var result = new ContextMenu();
-            PopulateRowMenu(result, row);
-            button.SetValue(ContextMenuProperty, result);
-            return result;
-        }
+    private void AddColumnBeforeClick(int column)
+    {
+        var length = new GridLength(1.0F, form.ColumnWidths.Count == 0 ? GridUnitType.Star : GridUnitType.Auto);
+        var result = GridLengthToString(length);
+        if (form.ColumnWidths.Count == 0)
+            form.ColumnWidths.Add(result);
+        else
+            form.ColumnWidths.Insert(column, result);
+        ShiftRight(column);
+        Render();
+    }
 
-        #endregion
+    private void AddColumnAfterClick(int column)
+    {
+        var length = new GridLength(1.0F, form.ColumnWidths.Count == 0 ? GridUnitType.Star : GridUnitType.Auto);
+
+        var result = GridLengthToString(length);
+        if (column == form.ColumnWidths.Count - 1)
+            form.ColumnWidths.Add(result);
+        else
+            form.ColumnWidths.Insert(column + 1, result);
+        ShiftRight(column + 1);
+        Render();
+    }
 
-        #region Columns
+    private void SplitColumn(int column)
+    {
+        foreach (var element in form.Elements)
+            if (element.Column > column)
+                element.Column++;
+            else if (element.Column == column)
+                element.ColumnSpan++;
+            else if (element.Column + element.ColumnSpan - 1 >= column)
+                element.ColumnSpan++;
+    }
 
-        private void ShiftRight(int column)
-        {
-            foreach (var element in form.Elements)
-                if (element.Column > column)
-                    element.Column++;
-                else if (element.Column + element.ColumnSpan - 1 > column)
-                    element.ColumnSpan++;
-        }
+    private void SplitColumnClick(int column)
+    {
+        var length = StringToGridLength(form.ColumnWidths[column]);
+        var newLength = length.GridUnitType == GridUnitType.Auto
+            ? length
+            : new GridLength(length.Value / 2, length.GridUnitType);
+        var result = GridLengthToString(newLength);
+        form.ColumnWidths[column] = result;
+
+        if (column == form.ColumnWidths.Count - 1)
+            form.ColumnWidths.Add(result);
+        else
+            form.ColumnWidths.Insert(column + 1, result);
+        SplitColumn(column + 1);
+        Render();
+    }
 
-        private void AddColumnBeforeClick(int column)
+    private void ColumnPropertiesClick(int column)
+    {
+        var length = StringToGridLength(form.ColumnWidths[column]);
+
+        var editor = new DynamicFormDesignLength(length);
+        if (editor.ShowDialog() == true)
         {
-            var length = new GridLength(1.0F, form.ColumnWidths.Count == 0 ? GridUnitType.Star : GridUnitType.Auto);
-            var result = GridLengthToString(length);
-            if (form.ColumnWidths.Count == 0)
-                form.ColumnWidths.Add(result);
-            else
-                form.ColumnWidths.Insert(column, result);
-            ShiftRight(column);
+            form.ColumnWidths[column] = GridLengthToString(editor.GridLength);
             Render();
         }
+    }
 
-        private void AddColumnAfterClick(int column)
-        {
-            var length = new GridLength(1.0F, form.ColumnWidths.Count == 0 ? GridUnitType.Star : GridUnitType.Auto);
+    private void ShiftLeft(int column)
+    {
+        var deletes = new List<DFLayoutControl>();
+        foreach (var element in form.Elements)
+            if (element.Column > column)
+                element.Column--;
+            else if (element.Column == column && element.ColumnSpan <= 1)
+                deletes.Add(element);
+            else if (element.Column + element.ColumnSpan - 1 >= column)
+                element.ColumnSpan--;
+        foreach (var delete in deletes)
+            form.Elements.Remove(delete);
+    }
 
-            var result = GridLengthToString(length);
-            if (column == form.ColumnWidths.Count - 1)
-                form.ColumnWidths.Add(result);
-            else
-                form.ColumnWidths.Insert(column + 1, result);
-            ShiftRight(column + 1);
-            Render();
+    private void DeleteColumns(Range columns)
+    {
+        for(var column = columns.Max; column >= columns.Min; --column)
+        {
+            form.ColumnWidths.RemoveAt(column);
+            ShiftLeft(column + 1);
         }
-
-        private void SplitColumn(int column)
+        if(form.ColumnWidths.Count == 0)
         {
-            foreach (var element in form.Elements)
-                if (element.Column > column)
-                    element.Column++;
-                else if (element.Column == column)
-                    element.ColumnSpan++;
-                else if (element.Column + element.ColumnSpan - 1 >= column)
-                    element.ColumnSpan++;
+            form.ColumnWidths.Add("*");
         }
+        Render();
+    }
 
-        private void SplitColumnClick(int column)
-        {
-            var length = StringToGridLength(form.ColumnWidths[column]);
-            var newLength = length.GridUnitType == GridUnitType.Auto
-                ? length
-                : new GridLength(length.Value / 2, length.GridUnitType);
-            var result = GridLengthToString(newLength);
-            form.ColumnWidths[column] = result;
+    private void PopulateColumnMenu(ContextMenu menu, int column)
+    {
+        menu.AddItem("Add Column Before", null, column, AddColumnBeforeClick);
+        menu.AddItem("Add Column After", null, column, AddColumnAfterClick);
+        menu.AddSeparator();
+        menu.AddItem("Split Column", null, column, SplitColumnClick);
+        var propertiesSeparator = menu.AddSeparator();
+        var propertiesMenu = menu.AddItem("Column Properties", null, column, ColumnPropertiesClick);
+        menu.AddSeparator();
+        menu.AddItem("Delete Column", null, new Range(column, column), DeleteColumns);
+        menu.Opened += (o, e) =>
+        {
+            propertiesSeparator.Visibility = form.ColumnWidths.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
+            propertiesMenu.Visibility = form.ColumnWidths.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
+        };
+    }
 
-            if (column == form.ColumnWidths.Count - 1)
-                form.ColumnWidths.Add(result);
-            else
-                form.ColumnWidths.Insert(column + 1, result);
-            SplitColumn(column + 1);
-            Render();
-        }
+    private ContextMenu CreateColumnMenu(Button button, int column)
+    {
+        var result = new ContextMenu();
+        PopulateColumnMenu(result, column);
+        button.SetValue(ContextMenuProperty, result);
+        return result;
+    }
 
-        private void ColumnPropertiesClick(int column)
-        {
-            var length = StringToGridLength(form.ColumnWidths[column]);
+    #endregion
 
-            var editor = new DynamicFormDesignLength(length);
-            if (editor.ShowDialog() == true)
-            {
-                form.ColumnWidths[column] = GridLengthToString(editor.GridLength);
-                Render();
-            }
-        }
+    #region Add Element
 
-        private void ShiftLeft(int column)
+    private void AddNewElement<TElement>(DynamicFormElement elementDef, CellRange range)
+        where TElement : DFLayoutElement, new()
+    {
+        TElement? element;
+        if (elementDef.CreateElement is not null)
         {
-            var deletes = new List<DFLayoutControl>();
-            foreach (var element in form.Elements)
-                if (element.Column > column)
-                    element.Column--;
-                else if (element.Column == column && element.ColumnSpan <= 1)
-                    deletes.Add(element);
-                else if (element.Column + element.ColumnSpan - 1 >= column)
-                    element.ColumnSpan--;
-            foreach (var delete in deletes)
-                form.Elements.Remove(delete);
+            element = elementDef.CreateElement(elementDef.Tag) as TElement;
         }
-
-        private void DeleteColumns(Range columns)
+        else
         {
-            for(var column = columns.Max; column >= columns.Min; --column)
-            {
-                form.ColumnWidths.RemoveAt(column);
-                ShiftLeft(column + 1);
-            }
-            if(form.ColumnWidths.Count == 0)
-            {
-                form.ColumnWidths.Add("*");
-            }
-            Render();
+            element = new();
         }
-
-        private void PopulateColumnMenu(ContextMenu menu, int column)
+        if(element is null)
         {
-            menu.AddItem("Add Column Before", null, column, AddColumnBeforeClick);
-            menu.AddItem("Add Column After", null, column, AddColumnAfterClick);
-            menu.AddSeparator();
-            menu.AddItem("Split Column", null, column, SplitColumnClick);
-            var propertiesSeparator = menu.AddSeparator();
-            var propertiesMenu = menu.AddItem("Column Properties", null, column, ColumnPropertiesClick);
-            menu.AddSeparator();
-            menu.AddItem("Delete Column", null, new Range(column, column), DeleteColumns);
-            menu.Opened += (o, e) =>
-            {
-                propertiesSeparator.Visibility = form.ColumnWidths.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
-                propertiesMenu.Visibility = form.ColumnWidths.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
-            };
+            return;
         }
+        SetControlRange(element, range);
 
-        private ContextMenu CreateColumnMenu(Button button, int column)
+        var result = new FormControlGrid<TElement>().EditItems(new[] { element });
+        if (result)
         {
-            var result = new ContextMenu();
-            PopulateColumnMenu(result, column);
-            button.SetValue(ContextMenuProperty, result);
-            return result;
+            form.Elements.Add(element);
+            Render();
         }
+    }
 
-        #endregion
-
-        #region Add Element
+    private void AddElementClick(Tuple<DynamicFormElement, CellRange> tuple)
+    {
+        var method = typeof(DynamicFormDesignGrid)
+            .GetMethod(nameof(AddNewElement), BindingFlags.NonPublic | BindingFlags.Instance)!
+            .MakeGenericMethod(tuple.Item1.ElementType);
+        method.Invoke(this, new object[] { tuple.Item1, tuple.Item2 });
+    }
 
-        private void AddNewElement<TElement>(DynamicFormElement elementDef, CellRange range)
-            where TElement : DFLayoutElement, new()
+    private void ElementActionClick(Tuple<DynamicFormElementAction, CellRange> tuple)
+    {
+        var element = tuple.Item1.OnClick(tuple.Item1.Tag);
+        if(element is not null)
         {
-            TElement? element;
-            if (elementDef.CreateElement is not null)
-            {
-                element = elementDef.CreateElement(elementDef.Tag) as TElement;
-            }
-            else
-            {
-                element = new();
-            }
-            if(element is null)
-            {
-                return;
-            }
-            SetControlRange(element, range);
-
-            var result = new FormControlGrid<TElement>().EditItems(new[] { element });
-            if (result)
-            {
-                form.Elements.Add(element);
-                Render();
-            }
+            SetControlRange(element, tuple.Item2);
+            form.Elements.Add(element);
+            Render();
         }
+    }
 
-        private void AddElementClick(Tuple<DynamicFormElement, CellRange> tuple)
-        {
-            var method = typeof(DynamicFormDesignGrid)
-                .GetMethod(nameof(AddNewElement), BindingFlags.NonPublic | BindingFlags.Instance)!
-                .MakeGenericMethod(tuple.Item1.ElementType);
-            method.Invoke(this, new object[] { tuple.Item1, tuple.Item2 });
-        }
+    private void SetControlRange(DFLayoutControl control, CellRange range)
+    {
+        var minRow = Math.Min(range.StartRow, range.EndRow);
+        var maxRow = Math.Max(range.StartRow, range.EndRow);
+        var minColumn = Math.Min(range.StartColumn, range.EndColumn);
+        var maxColumn = Math.Max(range.StartColumn, range.EndColumn);
+
+        control.Row = minRow;
+        control.RowSpan = (maxRow - minRow) + 1;
+        control.Column = minColumn;
+        control.ColumnSpan = (maxColumn - minColumn) + 1;
+    }
 
-        private void ElementActionClick(Tuple<DynamicFormElementAction, CellRange> tuple)
+    private void CreateLabelClick(CellRange range)
+    {
+        var label = new DFLayoutLabel();
+        SetControlRange(label, range);
+        var result = new FormControlGrid<DFLayoutLabel>().EditItems(new[] { label });
+        if (result)
         {
-            var element = tuple.Item1.OnClick(tuple.Item1.Tag);
-            if(element is not null)
-            {
-                SetControlRange(element, tuple.Item2);
-                form.Elements.Add(element);
-                Render();
-            }
+            form.Elements.Add(label);
+            Render();
         }
+    }
 
-        private void SetControlRange(DFLayoutControl control, CellRange range)
+    private void CreateHeaderClick(CellRange range)
+    {
+        var header = new DFLayoutHeader();
+        SetControlRange(header, range);
+        var result = new FormControlGrid<DFLayoutHeader>().EditItems(new[] { header });
+        if (result)
         {
-            var minRow = Math.Min(range.StartRow, range.EndRow);
-            var maxRow = Math.Max(range.StartRow, range.EndRow);
-            var minColumn = Math.Min(range.StartColumn, range.EndColumn);
-            var maxColumn = Math.Max(range.StartColumn, range.EndColumn);
-
-            control.Row = minRow;
-            control.RowSpan = (maxRow - minRow) + 1;
-            control.Column = minColumn;
-            control.ColumnSpan = (maxColumn - minColumn) + 1;
+            form.Elements.Add(header);
+            Render();
         }
+    }
 
-        private void CreateLabelClick(CellRange range)
+    private void CreateImageClick(CellRange range)
+    {
+        var image = new DFLayoutImage();
+        SetControlRange(image, range);
+        var result = new FormControlGrid<DFLayoutImage>().EditItems(new[] { image });
+        if (result)
         {
-            var label = new DFLayoutLabel();
-            SetControlRange(label, range);
-            var result = new FormControlGrid<DFLayoutLabel>().EditItems(new[] { label });
-            if (result)
-            {
-                form.Elements.Add(label);
-                Render();
-            }
+            form.Elements.Add(image);
+            Render();
         }
+    }
 
-        private void CreateHeaderClick(CellRange range)
+    private void AddVariable(Tuple<DigitalFormVariable, CellRange> tuple)
+    {
+        if(Activator.CreateInstance(tuple.Item1.FieldType()) is not DFLayoutField field)
         {
-            var header = new DFLayoutHeader();
-            SetControlRange(header, range);
-            var result = new FormControlGrid<DFLayoutHeader>().EditItems(new[] { header });
-            if (result)
-            {
-                form.Elements.Add(header);
-                Render();
-            }
+            MessageBox.Show(string.Format("{0}: Unknown Type {1}", tuple.Item1.Code, tuple.Item1.VariableType.ToString()));
+            return;
         }
 
-        private void CreateImageClick(CellRange range)
-        {
-            var image = new DFLayoutImage();
-            SetControlRange(image, range);
-            var result = new FormControlGrid<DFLayoutImage>().EditItems(new[] { image });
-            if (result)
-            {
-                form.Elements.Add(image);
-                Render();
-            }
-        }
+        field.Name = tuple.Item1.Code;
+        SetControlRange(field, tuple.Item2);
+        form.Elements.Add(field);
+        form.LoadVariable(tuple.Item1, field);
+        Render();
+    }
 
-        private void AddVariable(Tuple<DigitalFormVariable, CellRange> tuple)
-        {
-            if(Activator.CreateInstance(tuple.Item1.FieldType()) is not DFLayoutField field)
-            {
-                MessageBox.Show(string.Format("{0}: Unknown Type {1}", tuple.Item1.Code, tuple.Item1.VariableType.ToString()));
-                return;
-            }
+    private void PopulateEmptyCellMenu(ContextMenu menu, CellRange cellRange)
+    {
+        menu.Items.Clear();
+        menu.AddItem("Add Label", null, cellRange, CreateLabelClick);
+        menu.AddItem("Add Header", null, cellRange, CreateHeaderClick);
+        menu.AddItem("Add Image", null, cellRange, CreateImageClick);
 
-            field.Name = tuple.Item1.Code;
-            SetControlRange(field, tuple.Item2);
-            form.Elements.Add(field);
-            form.LoadVariable(tuple.Item1, field);
-            Render();
-        }
+        var fields = menu.AddItem("Add Field", null, null);
 
-        private void PopulateEmptyCellMenu(ContextMenu menu, CellRange cellRange)
+        if (OnCreateVariable is not null)
         {
-            menu.Items.Clear();
-            menu.AddItem("Add Label", null, cellRange, CreateLabelClick);
-            menu.AddItem("Add Header", null, cellRange, CreateHeaderClick);
-            menu.AddItem("Add Image", null, cellRange, CreateImageClick);
+            var variables = fields.AddItem("Create new variable", null, null);
 
-            var fields = menu.AddItem("Add Field", null, null);
-
-            if (OnCreateVariable is not null)
+            foreach (var fieldType in DFUtils.GetFieldTypes())
             {
-                var variables = fields.AddItem("Create new variable", null, null);
-
-                foreach (var fieldType in DFUtils.GetFieldTypes())
+                var caption = fieldType.GetCaption();
+                if (string.IsNullOrWhiteSpace(caption))
+                {
+                    caption = CoreUtils.Neatify(fieldType.Name);
+                }
+                variables.AddItem(caption, null, new Tuple<Type, CellRange>(fieldType, cellRange), (tuple) =>
                 {
-                    var caption = fieldType.GetCaption();
-                    if (string.IsNullOrWhiteSpace(caption))
+                    var variable = OnCreateVariable?.Invoke(tuple.Item1);
+                    if (variable is not null)
                     {
-                        caption = CoreUtils.Neatify(fieldType.Name);
+                        _variables.Add(variable);
+                        AddVariable(new(variable, tuple.Item2));
                     }
-                    variables.AddItem(caption, null, new Tuple<Type, CellRange>(fieldType, cellRange), (tuple) =>
-                    {
-                        var variable = OnCreateVariable?.Invoke(tuple.Item1);
-                        if (variable is not null)
-                        {
-                            _variables.Add(variable);
-                            AddVariable(new(variable, tuple.Item2));
-                        }
-                    });
-                }
+                });
             }
+        }
 
-            var filtered = _variables.Where(x => !x.Hidden && !form.Elements.Any(v => string.Equals((v as DFLayoutField)?.Name, x.Code)));
-            fields.AddSeparatorIfNeeded();
-            foreach (var variable in filtered)
-                fields.AddItem(variable.Code, null, new Tuple<DigitalFormVariable, CellRange>(variable, cellRange), AddVariable);
-            fields.RemoveUnnecessarySeparators();
-            if(fields.Items.Count == 0)
-            {
-                menu.Items.Remove(fields);
-            }
+        var filtered = _variables.Where(x => !x.Hidden && !form.Elements.Any(v => string.Equals((v as DFLayoutField)?.Name, x.Code)));
+        fields.AddSeparatorIfNeeded();
+        foreach (var variable in filtered)
+            fields.AddItem(variable.Code, null, new Tuple<DigitalFormVariable, CellRange>(variable, cellRange), AddVariable);
+        fields.RemoveUnnecessarySeparators();
+        if(fields.Items.Count == 0)
+        {
+            menu.Items.Remove(fields);
+        }
 
-            var elements = menu.AddItem("Add Object", null, cellRange, null);
+        var elements = menu.AddItem("Add Object", null, cellRange, null);
 
-            var available = _elements.Where(x => x.Visible && (x.AllowDuplicate || !form.Elements.Any(v => (v as DFLayoutElement)?.GetType() == x.ElementType)))
-                .ToArray();
+        var available = _elements.Where(x => x.Visible && (x.AllowDuplicate || !form.Elements.Any(v => (v as DFLayoutElement)?.GetType() == x.ElementType)))
+            .ToArray();
 
-            var cats = available.Select(x => x.Category).Concat(_elementActions.Select(x => x.Category)).Distinct().OrderBy(x => x);
-            foreach (var cat in cats)
+        var cats = available.Select(x => x.Category).Concat(_elementActions.Select(x => x.Category)).Distinct().OrderBy(x => x);
+        foreach (var cat in cats)
+        {
+            var parentMenu = elements;
+            if (!string.IsNullOrWhiteSpace(cat))
             {
-                var parentMenu = elements;
-                if (!string.IsNullOrWhiteSpace(cat))
-                {
-                    parentMenu = elements.AddItem(cat, null, null);
-                }
-
-                foreach(var action in _elementActions.Where(x => x.Category == cat))
-                {
-                    parentMenu.AddItem(action.Caption, action.Image, new Tuple<DynamicFormElementAction, CellRange>(action, cellRange), ElementActionClick);
-                }
-
-                parentMenu.AddSeparatorIfNeeded();
+                parentMenu = elements.AddItem(cat, null, null);
+            }
 
-                foreach (var element in available.Where(x => string.Equals(x.Category, cat)))
-                    parentMenu.AddItem(element.Caption, null, new Tuple<DynamicFormElement, CellRange>(element, cellRange), AddElementClick);
-                parentMenu.RemoveUnnecessarySeparators();
+            foreach(var action in _elementActions.Where(x => x.Category == cat))
+            {
+                parentMenu.AddItem(action.Caption, action.Image, new Tuple<DynamicFormElementAction, CellRange>(action, cellRange), ElementActionClick);
             }
 
-            if (elements.Items.Count == 0)
-                menu.Items.Remove(elements);
+            parentMenu.AddSeparatorIfNeeded();
+
+            foreach (var element in available.Where(x => string.Equals(x.Category, cat)))
+                parentMenu.AddItem(element.Caption, null, new Tuple<DynamicFormElement, CellRange>(element, cellRange), AddElementClick);
+            parentMenu.RemoveUnnecessarySeparators();
         }
 
-        private ContextMenu CreateEmptyCellMenu(Border border, int row, int column)
-        {
-            var result = new ContextMenu();
-            result.Opened += (o, e) =>
-            {
-                PopulateEmptyCellMenu(result, new CellRange(row, column));
-            };
+        if (elements.Items.Count == 0)
+            menu.Items.Remove(elements);
+    }
 
-            border.SetValue(ContextMenuProperty, result);
-            return result;
-        }
+    private ContextMenu CreateEmptyCellMenu(Border border, int row, int column)
+    {
+        var result = new ContextMenu();
+        result.Opened += (o, e) =>
+        {
+            PopulateEmptyCellMenu(result, new CellRange(row, column));
+        };
 
-        #endregion
+        border.SetValue(ContextMenuProperty, result);
+        return result;
+    }
 
-        #region Element Context Menu
+    #endregion
 
-        private void DeleteElements(IEnumerable<DFLayoutControl> controls)
-        {
-            foreach(var control in controls)
-            {
-                if (form.Elements.Contains(control))
-                {
-                    form.Elements.Remove(control);
-                }
-            }
-            Render();
-        }
+    #region Element Context Menu
 
-        private void DeleteElementClick(DFLayoutControl control)
+    private void DeleteElements(IEnumerable<DFLayoutControl> controls)
+    {
+        foreach(var control in controls)
         {
             if (form.Elements.Contains(control))
             {
                 form.Elements.Remove(control);
-                Render();
             }
         }
+        Render();
+    }
 
-        private void ElementPropertiesClick(DFLayoutControl control)
+    private void DeleteElementClick(DFLayoutControl control)
+    {
+        if (form.Elements.Contains(control))
         {
-            if(!elementgrids.TryGetValue(control.GetType(), out var grid))
-            {
-                var type = typeof(FormControlGrid<>).MakeGenericType(control.GetType());
-                grid = (Activator.CreateInstance(type) as IDynamicGrid)!;
-                elementgrids[control.GetType()] = grid;
-            }
-
-            control.CommitChanges();
-            if (grid.EditItems(new[] { control }))
-            {
-                Render();
-            }
+            form.Elements.Remove(control);
+            Render();
         }
+    }
 
-        private void EditVariableClick(DFLayoutField field)
+    private void ElementPropertiesClick(DFLayoutControl control)
+    {
+        if(!elementgrids.TryGetValue(control.GetType(), out var grid))
         {
-            var variable = _variables.FirstOrDefault(x => x.Code == field.Name);
-            if (variable is null) return;
-
-            if(OnEditVariable?.Invoke(variable) == true)
-            {
-                field.LoadFromString(variable.Parameters);
-            }
+            var type = typeof(FormControlGrid<>).MakeGenericType(control.GetType());
+            grid = (Activator.CreateInstance(type) as IDynamicGrid)!;
+            elementgrids[control.GetType()] = grid;
         }
 
-        private void ConvertToHeaderClick(DFLayoutLabel label)
+        control.CommitChanges();
+        if (grid.EditItems(new[] { control }))
         {
-            var header = new DFLayoutHeader
-            {
-                Row = label.Row,
-                RowSpan = label.RowSpan,
-                Column = label.Column,
-                ColumnSpan = label.ColumnSpan,
-                Collapsed = false,
-                Header = label.Caption
-            };
-            header.Style.Synchronise(label.Style);
-            header.Style.IsBold = true;
-            form.Elements.Remove(label);
-            form.Elements.Add(header);
             Render();
         }
+    }
+
+    private void EditVariableClick(DFLayoutField field)
+    {
+        var variable = _variables.FirstOrDefault(x => x.Code == field.Name);
+        if (variable is null) return;
 
-        private void ConvertToLabelClick(DFLayoutHeader header)
+        if(OnEditVariable?.Invoke(variable) == true)
         {
-            var label = new DFLayoutLabel
-            {
-                Row = header.Row,
-                RowSpan = header.RowSpan,
-                Column = header.Column,
-                ColumnSpan = header.ColumnSpan,
-                Caption = header.Header
-            };
-            label.Style.Synchronise(header);
-            label.Style.IsBold = false;
+            field.LoadFromString(variable.Parameters);
+        }
+    }
 
-            form.Elements.Remove(header);
-            form.Elements.Add(label);
-            Render();
+    private void ConvertToHeaderClick(DFLayoutLabel label)
+    {
+        var header = new DFLayoutHeader
+        {
+            Row = label.Row,
+            RowSpan = label.RowSpan,
+            Column = label.Column,
+            ColumnSpan = label.ColumnSpan,
+            Collapsed = false,
+            Header = label.Caption
+        };
+        header.Style.Synchronise(label.Style);
+        header.Style.IsBold = true;
+        form.Elements.Remove(label);
+        form.Elements.Add(header);
+        Render();
+    }
+
+    private void ConvertToLabelClick(DFLayoutHeader header)
+    {
+        var label = new DFLayoutLabel
+        {
+            Row = header.Row,
+            RowSpan = header.RowSpan,
+            Column = header.Column,
+            ColumnSpan = header.ColumnSpan,
+            Caption = header.Header
+        };
+        label.Style.Synchronise(header);
+        label.Style.IsBold = false;
+
+        form.Elements.Remove(header);
+        form.Elements.Add(label);
+        Render();
+    }
+
+    private void PopulateElementContextMenu(ContextMenu menu, DFLayoutControl control)
+    {
+        var selectedItems = GetSelectedItems().ToList();
+        if (selectedItems.Count > 1 && selectedItems.Contains(control))
+        {
+            PopulateSelectionMenu(menu);
+            if(menu.Items.Count > 0) return;
         }
 
-        private void PopulateElementContextMenu(ContextMenu menu, DFLayoutControl control)
+        menu.AddItem("Edit Properties", null, control, ElementPropertiesClick);
+        if (OnEditVariable is not null && control is DFLayoutField field)
         {
-            var selectedItems = GetSelectedItems().ToList();
-            if (selectedItems.Count > 1 && selectedItems.Contains(control))
-            {
-                PopulateSelectionMenu(menu);
-                if(menu.Items.Count > 0) return;
-            }
-
-            menu.AddItem("Edit Properties", null, control, ElementPropertiesClick);
-            if (OnEditVariable is not null && control is DFLayoutField field)
-            {
-                menu.AddItem("Edit Variable", null, field, EditVariableClick);
-            }
-            else if (control is DFLayoutLabel label)
-            {
-                menu.AddItem("Convert to Header", null, label, ConvertToHeaderClick);
-            }
-            else if (control is DFLayoutHeader header)
-            {
-                menu.AddItem("Convert to Label", null, header, ConvertToLabelClick);
-            }
-            else if(control is DFLayoutElement element)
-            {
-                CustomiseElementContextMenu?.Invoke(menu, element);
-            }
-            menu.AddSeparatorIfNeeded();
-            menu.AddItem("Resize Item", null, control, ResizeItem);
-            menu.AddItem("Delete Item", null, control, DeleteElementClick);
+            menu.AddItem("Edit Variable", null, field, EditVariableClick);
         }
-
-        private ContextMenu CreateElementContextMenu(FrameworkElement element, DFLayoutControl control)
+        else if (control is DFLayoutLabel label)
         {
-            var result = new ContextMenu();
-            result.Opened += (s, e) =>
-            {
-                result.Items.Clear();
-                PopulateElementContextMenu(result, control);
-            };
-            element.SetValue(ContextMenuProperty, result);
-            return result;
+            menu.AddItem("Convert to Header", null, label, ConvertToHeaderClick);
         }
+        else if (control is DFLayoutHeader header)
+        {
+            menu.AddItem("Convert to Label", null, header, ConvertToLabelClick);
+        }
+        else if(control is DFLayoutElement element)
+        {
+            CustomiseElementContextMenu?.Invoke(menu, element);
+        }
+        menu.AddSeparatorIfNeeded();
+        menu.AddItem("Resize Item", null, control, ResizeItem);
+        menu.AddItem("Delete Item", null, control, DeleteElementClick);
+    }
 
-        #endregion
+    private ContextMenu CreateElementContextMenu(FrameworkElement element, DFLayoutControl control)
+    {
+        var result = new ContextMenu();
+        result.Opened += (s, e) =>
+        {
+            result.Items.Clear();
+            PopulateElementContextMenu(result, control);
+        };
+        element.SetValue(ContextMenuProperty, result);
+        return result;
+    }
 
-        #endregion
+    #endregion
 
-        #region Render
+    #endregion
 
-        private static void SetDimensions(FrameworkElement element, int row, int column, int rowspan, int colspan, int offset)
-        {
-            if (column <= 0) return;
-            if (row <= 0) return;
+    #region Render
 
-            element.MinHeight = 50.0F;
-            element.MinWidth = 50.0F;
-            element.SetGridPosition(row - offset, column - offset, rowspan, colspan);
-        }
+    private static void SetDimensions(FrameworkElement element, int row, int column, int rowspan, int colspan, int offset)
+    {
+        if (column <= 0) return;
+        if (row <= 0) return;
+
+        element.MinHeight = 50.0F;
+        element.MinWidth = 50.0F;
+        element.SetGridPosition(row - offset, column - offset, rowspan, colspan);
+    }
 
-        private Border CreateBorder(int row, int column, int rowspan, int colspan, int offset, bool horzstar, bool vertstar)
+    private Border CreateBorder(int row, int column, int rowspan, int colspan, int offset, bool horzstar, bool vertstar)
+    {
+        var border = new Border();
+        if (ShowBorders)
         {
-            var border = new Border();
-            if (ShowBorders)
-            {
-                border.BorderThickness = new Thickness(
-                    0.0F,//!IsDesigning && column == 1 - offset ? 0.00F /*0.75F*/ : 0.0F,
-                    0.0F,//!IsDesigning && row == 1 - offset ? 0.00F /*0.75F*/ : 0.0F,
-                    column - offset == ColumnDefinitions.Count - 1 ? horzstar ? 0.00F : 0.75F : 0.75F,
-                    row - offset == RowDefinitions.Count - 1 ? vertstar ? 0.00F : 0.75F : 0.75F
-                );
+            border.BorderThickness = new Thickness(
+                0.0F,//!IsDesigning && column == 1 - offset ? 0.00F /*0.75F*/ : 0.0F,
+                0.0F,//!IsDesigning && row == 1 - offset ? 0.00F /*0.75F*/ : 0.0F,
+                column - offset == ColumnDefinitions.Count - 1 ? horzstar ? 0.00F : 0.75F : 0.75F,
+                row - offset == RowDefinitions.Count - 1 ? vertstar ? 0.00F : 0.75F : 0.75F
+            );
 
-                border.BorderBrush = BorderBrush;
-            }
+            border.BorderBrush = BorderBrush;
+        }
 
-            border.Background = BackgroundBrush;
+        border.Background = BackgroundBrush;
 
-            SetDimensions(border, row, column, rowspan, colspan, offset);
+        SetDimensions(border, row, column, rowspan, colspan, offset);
 
-            return border;
-        }
+        return border;
+    }
 
-        private static BitmapImage HeaderClosed =Wpf.Resources.rightarrow.AsBitmapImage(32, 32);
-        private static BitmapImage HeaderOpen =Wpf.Resources.downarrow.AsBitmapImage(32, 32);
+    private static BitmapImage HeaderClosed =Wpf.Resources.rightarrow.AsBitmapImage(32, 32);
+    private static BitmapImage HeaderOpen =Wpf.Resources.downarrow.AsBitmapImage(32, 32);
 
-        private FrameworkElement CreateHeader(DFLayoutHeader header)
+    private FrameworkElement CreateHeader(DFLayoutHeader header)
+    {
+        var formHeader = new FormHeader
         {
-            var formHeader = new FormHeader
-            {
-                Collapsed = header.Collapsed,
-                HeaderText = header.Header
-            };
-            formHeader.CollapsedChanged += (o, c) =>
-            {
-                CollapseRows(formHeader, c);
-            };
-            if (IsDesigning)
-            {
-                formHeader.IsEnabled = false;
-            }
-            return formHeader;
+            Collapsed = header.Collapsed,
+            HeaderText = header.Header
+        };
+        formHeader.CollapsedChanged += (o, c) =>
+        {
+            CollapseRows(formHeader, c);
+        };
+        if (IsDesigning)
+        {
+            formHeader.IsEnabled = false;
         }
+        return formHeader;
+    }
 
-        // DFLayoutField -> IDynamicFormFieldControl
-        private static Dictionary<Type, Type>? _fieldControls;
-        private DynamicFormControl? CreateFieldControl(DFLayoutField field)
+    // DFLayoutField -> IDynamicFormFieldControl
+    private static Dictionary<Type, Type>? _fieldControls;
+    private DynamicFormControl? CreateFieldControl(DFLayoutField field)
+    {
+        if (_fieldControls == null)
         {
-            if (_fieldControls == null)
-            {
-                _fieldControls = new();
-                foreach (var controlType in CoreUtils.Entities.Where(x => x.IsClass && !x.IsGenericType && x.HasInterface<IDynamicFormFieldControl>()))
-                {
-                    var superDefinition = controlType.GetSuperclassDefinition(typeof(DynamicFormFieldControl<,,,>));
-                    if (superDefinition != null)
-                    {
-                        _fieldControls[superDefinition.GenericTypeArguments[0]] = controlType;
-                    }
-                }
-            }
-
-            var fieldControlType = _fieldControls.GetValueOrDefault(field.GetType());
-            if (fieldControlType is not null)
+            _fieldControls = new();
+            foreach (var controlType in CoreUtils.Entities.Where(x => x.IsClass && !x.IsGenericType && x.HasInterface<IDynamicFormFieldControl>()))
             {
-                var element = (Activator.CreateInstance(fieldControlType) as DynamicFormControl)!;
-
-                if(element is IDynamicFormFieldControl fieldControl)
+                var superDefinition = controlType.GetSuperclassDefinition(typeof(DynamicFormFieldControl<,,,>));
+                if (superDefinition != null)
                 {
-                    fieldControl.FieldChangedEvent += () =>
-                    {
-                        ChangeField(field.Name);
-                    };
+                    _fieldControls[superDefinition.GenericTypeArguments[0]] = controlType;
                 }
-
-                return element;
             }
-            return null;
         }
 
-        private DynamicFormControl? CreateFieldPlaceholder(DFLayoutField field)
+        var fieldControlType = _fieldControls.GetValueOrDefault(field.GetType());
+        if (fieldControlType is not null)
         {
-            var controlType = typeof(DFFieldPlaceholderControl<>).MakeGenericType(field.GetType());
-            return Activator.CreateInstance(controlType) as DynamicFormControl;
-        }
+            var element = (Activator.CreateInstance(fieldControlType) as DynamicFormControl)!;
 
-        private DynamicFormControl? CreateControl(DFLayoutControl item)
-        {
-            if (item is DFLayoutField field)
+            if(element is IDynamicFormFieldControl fieldControl)
             {
-                if (IsDesigning)
+                fieldControl.FieldChangedEvent += () =>
                 {
-                    return CreateFieldPlaceholder(field);
-                }
-
-                return CreateFieldControl(field);
-            }
-            else if (item is DFLayoutElement)
-            {
-                return IsDesigning
-                    ? new DFElementPlaceholderControl()
-                    : new DFElementControl();
-            }
-            else if (item is DFLayoutLabel)
-            {
-                return new DFLabelControl();
-            }
-            else if (item is DFLayoutHeader)
-            {
-                return new DFHeaderControl();
-            }
-            else if (item is DFLayoutImage)
-            {
-                return new DFImageControl();
+                    ChangeField(field.Name);
+                };
             }
 
-            return null;
+            return element;
         }
+        return null;
+    }
+
+    private DynamicFormControl? CreateFieldPlaceholder(DFLayoutField field)
+    {
+        var controlType = typeof(DFFieldPlaceholderControl<>).MakeGenericType(field.GetType());
+        return Activator.CreateInstance(controlType) as DynamicFormControl;
+    }
 
-        private FrameworkElement? CreateElement(DFLayoutControl item)
+    private DynamicFormControl? CreateControl(DFLayoutControl item)
+    {
+        if (item is DFLayoutField field)
         {
-            var control = CreateControl(item);
-            if(control != null)
+            if (IsDesigning)
             {
-                control.FormDesignGrid = this;
-                control.SetControl(item);
+                return CreateFieldPlaceholder(field);
             }
-            return control;
-        }
 
-        private Brush GetItemBackgroundBrush(DFLayoutControl item, Color? colour = null)
+            return CreateFieldControl(field);
+        }
+        else if (item is DFLayoutElement)
         {
-            if(colour != null)
-            {
-                var colourValue = colour.Value;
-                return new SolidColorBrush(new System.Windows.Media.Color { R = colourValue.R, G = colourValue.G, B = colourValue.B, A = colourValue.A });
-            }
+            return IsDesigning
+                ? new DFElementPlaceholderControl()
+                : new DFElementControl();
+        }
+        else if (item is DFLayoutLabel)
+        {
+            return new DFLabelControl();
+        }
+        else if (item is DFLayoutHeader)
+        {
+            return new DFHeaderControl();
+        }
+        else if (item is DFLayoutImage)
+        {
+            return new DFImageControl();
+        }
 
-            if (item is DFLayoutField field)
-                return field.GetPropertyValue<bool>("Required") ? RequiredFieldBrush : FieldBrush;
-            else
-                return IsDesigning ? FieldBrush : BackgroundBrush;
+        return null;
+    }
+
+    private FrameworkElement? CreateElement(DFLayoutControl item)
+    {
+        var control = CreateControl(item);
+        if(control != null)
+        {
+            control.FormDesignGrid = this;
+            control.SetControl(item);
         }
+        return control;
+    }
 
-        private void RenderElement(DFLayoutControl item, int offset, bool horzstar, bool vertstar)
+    private Brush GetItemBackgroundBrush(DFLayoutControl item, Color? colour = null)
+    {
+        if(colour != null)
         {
-            var border = CreateBorder(item.Row, item.Column, item.RowSpan, item.ColumnSpan, offset, horzstar, vertstar);
+            var colourValue = colour.Value;
+            return new SolidColorBrush(new System.Windows.Media.Color { R = colourValue.R, G = colourValue.G, B = colourValue.B, A = colourValue.A });
+        }
 
-            border.Background = GetItemBackgroundBrush(item);
+        if (item is DFLayoutField field)
+            return field.GetPropertyValue<bool>("Required") ? RequiredFieldBrush : FieldBrush;
+        else
+            return IsDesigning ? FieldBrush : BackgroundBrush;
+    }
 
-            if (!ShowBorders)
-                border.Padding = new Thickness(
-                    item.Column == 1 ? 4 : 2,
-                    item.Row == 1 ? 4 : 2,
-                    item.Column + item.ColumnSpan - 1 == ColumnDefinitions.Count ? 4 : 2,
-                    item.Row + item.RowSpan - 1 == RowDefinitions.Count ? 4 : 2
-                );
-            else
-                border.Padding = new Thickness(5);
+    private void RenderElement(DFLayoutControl item, int offset, bool horzstar, bool vertstar)
+    {
+        var border = CreateBorder(item.Row, item.Column, item.RowSpan, item.ColumnSpan, offset, horzstar, vertstar);
 
-            var element = CreateElement(item);
-            border.Child = element;
-            Children.Add(border);
-            if (IsDesigning)
+        border.Background = GetItemBackgroundBrush(item);
+
+        if (!ShowBorders)
+            border.Padding = new Thickness(
+                item.Column == 1 ? 4 : 2,
+                item.Row == 1 ? 4 : 2,
+                item.Column + item.ColumnSpan - 1 == ColumnDefinitions.Count ? 4 : 2,
+                item.Row + item.RowSpan - 1 == RowDefinitions.Count ? 4 : 2
+            );
+        else
+            border.Padding = new Thickness(5);
+
+        var element = CreateElement(item);
+        border.Child = element;
+        Children.Add(border);
+        if (IsDesigning)
+        {
+            CreateElementContextMenu(border, item);
+        }
+        borderMap[item] = border;
+
+        if (element != null)
+        {
+            if(item is DFLayoutField)
             {
-                CreateElementContextMenu(border, item);
+                element.IsEnabled = element.IsEnabled && !IsReadOnly;
             }
-            borderMap[item] = border;
+            elementmap[item] = element;
 
-            if (element != null)
+            element.HorizontalAlignment = GetHorizontalAlignment(item.HorizontalAlignment);
+            element.VerticalAlignment = GetVerticalAlignment(item.VerticalAlignment);
+            if (IsDesigning)
             {
-                if(item is DFLayoutField)
-                {
-                    element.IsEnabled = element.IsEnabled && !IsReadOnly;
-                }
-                elementmap[item] = element;
-
-                element.HorizontalAlignment = GetHorizontalAlignment(item.HorizontalAlignment);
-                element.VerticalAlignment = GetVerticalAlignment(item.VerticalAlignment);
-                if (IsDesigning)
-                {
-                    CreateElementContextMenu(element, item);
-                }
+                CreateElementContextMenu(element, item);
             }
-
         }
 
-        private void AfterRender()
+    }
+
+    private void AfterRender()
+    {
+        if (!IsDesigning)
         {
-            if (!IsDesigning)
+            foreach (var header in elementmap.Where(x => x.Value is DFHeaderControl head).Select(x => x.Value).Cast<DFHeaderControl>())
             {
-                foreach (var header in elementmap.Where(x => x.Value is DFHeaderControl head).Select(x => x.Value).Cast<DFHeaderControl>())
+                if (header.Header.Collapsed)
                 {
-                    if (header.Header.Collapsed)
-                    {
-                        CollapseRows(header.Header, true);
-                    }
+                    CollapseRows(header.Header, true);
                 }
             }
-
-            OnAfterRender?.Invoke(this);
         }
 
-        private void Render()
+        OnAfterRender?.Invoke(this);
+    }
+
+    private void Render()
+    {
+        ClearSelection();
+        ClearResize();
+
+        foreach (var item in elementmap.Keys)
         {
-            ClearSelection();
-            ClearResize();
+            var e = elementmap[item];
+            if (VisualTreeHelper.GetParent(e) is Border parent)
+                parent.Child = null;
+        }
 
-            foreach (var item in elementmap.Keys)
-            {
-                var e = elementmap[item];
-                if (VisualTreeHelper.GetParent(e) is Border parent)
-                    parent.Child = null;
-            }
+        elementmap.Clear();
 
-            elementmap.Clear();
+        Children.Clear();
 
-            Children.Clear();
+        ColumnDefinitions.Clear();
 
-            ColumnDefinitions.Clear();
+        RowDefinitions.Clear();
 
-            RowDefinitions.Clear();
+        if (form == null)
+            return;
 
-            if (form == null)
-                return;
+        foreach (var column in form.ColumnWidths)
+            ColumnDefinitions.Add(new ColumnDefinition { Width = StringToGridLength(column) });
 
-            foreach (var column in form.ColumnWidths)
-                ColumnDefinitions.Add(new ColumnDefinition { Width = StringToGridLength(column) });
+        foreach (var row in form.RowHeights)
+            RowDefinitions.Add(new RowDefinition { Height = StringToGridLength(row), Tag = new RowData(row) });
 
-            foreach (var row in form.RowHeights)
-                RowDefinitions.Add(new RowDefinition { Height = StringToGridLength(row), Tag = new RowData(row) });
+        var horzstar = ColumnDefinitions.Any(x => x.Width.IsStar);
+        var vertstar = RowDefinitions.Any(x => x.Height.IsStar);
 
-            var horzstar = ColumnDefinitions.Any(x => x.Width.IsStar);
-            var vertstar = RowDefinitions.Any(x => x.Height.IsStar);
+        var offset = 1;
+        if (IsDesigning)
+        {
+            ColumnDefinitions.Insert(0, new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
+            RowDefinitions.Insert(0, new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
 
-            var offset = 1;
-            if (IsDesigning)
+            var topleft = new Button();
+            topleft.SetValue(RowProperty, 0);
+            topleft.SetValue(ColumnProperty, 0);
+            topleft.Content =
+                ""; // new Image() { Source = _designing ? Wpf.Resources.view.AsBitmapImage() : Wpf.Resources.design.AsBitmapImage() };
+            topleft.BorderBrush = BorderBrush;
+            topleft.BorderThickness = new Thickness(
+                0.00F,
+                0.00F,
+                0.75F,
+                0.75F
+            );
+            topleft.Background = BackgroundBrush;
+            //topleft.Click += (o, e) =>
+            //{
+            //    Designing = !Designing;
+            //};
+            Children.Add(topleft);
+
+            for (var i = 1; i < ColumnDefinitions.Count; i++)
             {
-                ColumnDefinitions.Insert(0, new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
-                RowDefinitions.Insert(0, new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
-
-                var topleft = new Button();
-                topleft.SetValue(RowProperty, 0);
-                topleft.SetValue(ColumnProperty, 0);
-                topleft.Content =
-                    ""; // new Image() { Source = _designing ? Wpf.Resources.view.AsBitmapImage() : Wpf.Resources.design.AsBitmapImage() };
-                topleft.BorderBrush = BorderBrush;
-                topleft.BorderThickness = new Thickness(
-                    0.00F,
-                    0.00F,
-                    0.75F,
+                var Button = new Button();
+                Button.SetValue(RowProperty, 0);
+                Button.SetValue(ColumnProperty, i);
+                Button.Content = FormatGridLength(ColumnDefinitions[i].Width, ColumnDefinitions.Select(x => x.Width));
+                Button.BorderBrush = BorderBrush;
+                Button.BorderThickness = new Thickness(
+                    0.00F, //(i == 1) ? 0.75F : 0.0F,
+                    0.00F, //0.75F,
+                    i == ColumnDefinitions.Count - 1 ? horzstar ? 0.00F : 0.75F : 0.75F,
                     0.75F
                 );
-                topleft.Background = BackgroundBrush;
-                //topleft.Click += (o, e) =>
-                //{
-                //    Designing = !Designing;
-                //};
-                Children.Add(topleft);
-
-                for (var i = 1; i < ColumnDefinitions.Count; i++)
-                {
-                    var Button = new Button();
-                    Button.SetValue(RowProperty, 0);
-                    Button.SetValue(ColumnProperty, i);
-                    Button.Content = FormatGridLength(ColumnDefinitions[i].Width, ColumnDefinitions.Select(x => x.Width));
-                    Button.BorderBrush = BorderBrush;
-                    Button.BorderThickness = new Thickness(
-                        0.00F, //(i == 1) ? 0.75F : 0.0F,
-                        0.00F, //0.75F,
-                        i == ColumnDefinitions.Count - 1 ? horzstar ? 0.00F : 0.75F : 0.75F,
-                        0.75F
-                    );
-                    Button.Background = BackgroundBrush;
-                    Button.Padding = new Thickness(10);
-                    Button.MinHeight = 35;
-                    CreateColumnMenu(Button, i - 1);
-                    AddClick(Button, i - 1, ColumnPropertiesClick);
-                    Children.Add(Button);
-                }
+                Button.Background = BackgroundBrush;
+                Button.Padding = new Thickness(10);
+                Button.MinHeight = 35;
+                CreateColumnMenu(Button, i - 1);
+                AddClick(Button, i - 1, ColumnPropertiesClick);
+                Children.Add(Button);
+            }
+
+            for (var i = 1; i < RowDefinitions.Count; i++)
+            {
+                var Button = new Button();
+                Button.SetValue(RowProperty, i);
+                Button.SetValue(ColumnProperty, 0);
+                Button.Content = FormatGridLength(RowDefinitions[i].Height, RowDefinitions.Select(x => x.Height));
+                Button.BorderBrush = BorderBrush;
+                Button.BorderThickness = new Thickness(
+                    0.00F, //0.75F,
+                    0.00F, //(i == 1) ? 0.75F : 0.0F,
+                    0.75F,
+                    i == RowDefinitions.Count - 1 ? vertstar ? 0.00F : 0.75F : 0.75F
+                );
+                Button.Background = BackgroundBrush;
+                Button.Padding = new Thickness(10);
+                CreateRowMenu(Button, i - 1);
+                AddClick(Button, i - 1, RowPropertiesClick);
+                Children.Add(Button);
+            }
+
+            offset = 0;
+        }
 
-                for (var i = 1; i < RowDefinitions.Count; i++)
+        var filledcells = new HashSet<PointI>();
+        foreach (var item in form.GetElements(IsDesigning))
+        {
+            try
+            {
+                if(item.Row > 0 && item.Column > 0)
                 {
-                    var Button = new Button();
-                    Button.SetValue(RowProperty, i);
-                    Button.SetValue(ColumnProperty, 0);
-                    Button.Content = FormatGridLength(RowDefinitions[i].Height, RowDefinitions.Select(x => x.Height));
-                    Button.BorderBrush = BorderBrush;
-                    Button.BorderThickness = new Thickness(
-                        0.00F, //0.75F,
-                        0.00F, //(i == 1) ? 0.75F : 0.0F,
-                        0.75F,
-                        i == RowDefinitions.Count - 1 ? vertstar ? 0.00F : 0.75F : 0.75F
-                    );
-                    Button.Background = BackgroundBrush;
-                    Button.Padding = new Thickness(10);
-                    CreateRowMenu(Button, i - 1);
-                    AddClick(Button, i - 1, RowPropertiesClick);
-                    Children.Add(Button);
+                    RenderElement(item, offset, horzstar, vertstar);
+                    for (var c = item.Column; c < item.Column + item.ColumnSpan; c++)
+                        for (var r = item.Row; r < item.Row + item.RowSpan; r++)
+                            filledcells.Add(new PointI(c, r));
                 }
-
-                offset = 0;
             }
-
-            var filledcells = new List<Point>();
-            foreach (var item in form.GetElements(IsDesigning))
+            catch (Exception e)
             {
-                try
+                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+            }
+        }
+
+        for (var c = 1; c <= form.ColumnWidths.Count; c++)
+            for (var r = 1; r <= form.RowHeights.Count; r++)
+                if (!filledcells.Contains(new(c, r)))
                 {
-                    if(item.Row > 0 && item.Column > 0)
+                    var border = CreateBorder(r, c, 1, 1, offset, horzstar, vertstar);
+                    if (IsDesigning)
                     {
-                        RenderElement(item, offset, horzstar, vertstar);
-                        for (var c = item.Column; c < item.Column + item.ColumnSpan; c++)
-                            for (var r = item.Row; r < item.Row + item.RowSpan; r++)
-                                filledcells.Add(new Point(c, r));
+                        CreateEmptyCellMenu(border, r, c);
                     }
+                    Children.Add(border);
                 }
-                catch (Exception e)
-                {
-                    Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                }
-            }
 
-            for (var c = 1; c <= form.ColumnWidths.Count; c++)
-                for (var r = 1; r <= form.RowHeights.Count; r++)
-                    if (!filledcells.Any(x => x.X.Equals(c) && x.Y.Equals(r)))
-                    {
-                        var border = CreateBorder(r, c, 1, 1, offset, horzstar, vertstar);
-                        if (IsDesigning)
-                        {
-                            CreateEmptyCellMenu(border, r, c);
-                        }
-                        Children.Add(border);
-                    }
+        AfterRender();
+    }
 
-            AfterRender();
-        }
+    #endregion
+
+    /// <summary>
+    /// Renders the form; after this is called, any changes to properties triggers a refresh.
+    /// </summary>
+    /// <remarks>
+    /// This should be called before <see cref="LoadValues(Dictionary{string, object})"/> or <see cref="SaveValues"/>
+    /// </remarks>
+    public void Initialize()
+    {
+        GridInitialized = true;
+        CheckRefresh(false);
+    }
+
+    public void Refresh()
+    {
+        CheckRefresh(false);
+    }
 
-        #endregion
+    private void CheckRefresh(bool keepValues = true)
+    {
+        if (!GridInitialized) return;
 
-        /// <summary>
-        /// Renders the form; after this is called, any changes to properties triggers a refresh.
-        /// </summary>
-        /// <remarks>
-        /// This should be called before <see cref="LoadValues(Dictionary{string, object})"/> or <see cref="SaveValues"/>
-        /// </remarks>
-        public void Initialize()
+        if (_mode == FormMode.Designing)
         {
-            GridInitialized = true;
-            CheckRefresh(false);
+            Render();
         }
-
-        public void Refresh()
+        else if(keepValues)
         {
-            CheckRefresh(false);
+            var values = SaveValues();
+            Render();
+            LoadValues(values.ToLoadStorage());
         }
-
-        private void CheckRefresh(bool keepValues = true)
+        else
         {
-            if (!GridInitialized) return;
-
-            if (_mode == FormMode.Designing)
-            {
-                Render();
-            }
-            else if(keepValues)
-            {
-                var values = SaveValues();
-                Render();
-                LoadValues(values.ToLoadStorage());
-            }
-            else
-            {
-                Render();
-                Form.EvaluateExpressions();
-            }
+            Render();
+            Form.EvaluateExpressions();
         }
+    }
 
-        #region Fields
+    #region Fields
 
-        private void ChangeField(string fieldName)
+    private void ChangeField(string fieldName)
+    {
+        if (!_changing)
         {
-            if (!_changing)
-            {
-                form.ChangeField(fieldName);
-                _isChanged = true;
-                OnChanged?.Invoke(this, fieldName);
-            }
+            form.ChangeField(fieldName);
+            _isChanged = true;
+            OnChanged?.Invoke(this, fieldName);
         }
+    }
 
-        private IDynamicFormFieldControl? GetFieldControl(DFLayoutField field)
-        {
-            return elementmap.GetValueOrDefault(field) as IDynamicFormFieldControl;
-        }
+    private IDynamicFormFieldControl? GetFieldControl(DFLayoutField field)
+    {
+        return elementmap.GetValueOrDefault(field) as IDynamicFormFieldControl;
+    }
 
-        private void LoadFieldValue(string fieldName, DFLoadStorageEntry entry)
+    private void LoadFieldValue(string fieldName, DFLoadStorageEntry entry)
+    {
+        var field = form.Elements.FirstOrDefault(x => string.Equals(fieldName, (x as DFLayoutField)?.Name)) as DFLayoutField;
+        if (field != null)
         {
-            var field = form.Elements.FirstOrDefault(x => string.Equals(fieldName, (x as DFLayoutField)?.Name)) as DFLayoutField;
-            if (field != null)
+            var fieldControl = GetFieldControl(field);
+            if (fieldControl != null)
             {
-                var fieldControl = GetFieldControl(field);
-                if (fieldControl != null)
-                {
-                    string? property = (DataModel != null) ? field.GetPropertyValue<string>("Property") : null;
-                    if (!property.IsNullOrWhiteSpace())
-                        fieldControl.SetValue(DataModel!.GetEntityValue(property));
-                    else
-                        fieldControl.Deserialize(entry);
-                }
+                string? property = (DataModel != null) ? field.GetPropertyValue<string>("Property") : null;
+                if (!property.IsNullOrWhiteSpace())
+                    fieldControl.SetValue(DataModel!.GetEntityValue(property));
+                else
+                    fieldControl.Deserialize(entry);
             }
         }
+    }
 
-        public void SetFieldValue(string fieldName, object? value)
+    public void SetFieldValue(string fieldName, object? value)
+    {
+        var field = form.Elements.FirstOrDefault(x => string.Equals(fieldName, (x as DFLayoutField)?.Name)) as DFLayoutField;
+        if (field != null)
         {
-            var field = form.Elements.FirstOrDefault(x => string.Equals(fieldName, (x as DFLayoutField)?.Name)) as DFLayoutField;
-            if (field != null)
+            var fieldControl = GetFieldControl(field);
+            if (fieldControl != null)
             {
-                var fieldControl = GetFieldControl(field);
-                if (fieldControl != null)
-                {
-                    string? property = (DataModel != null) ? field.GetPropertyValue<string>("Property") : null;
-                    if (!property.IsNullOrWhiteSpace())
-                        fieldControl.SetValue(DataModel!.GetEntityValue(property));
-                    else
-                        fieldControl.SetValue(value);
-                }
+                string? property = (DataModel != null) ? field.GetPropertyValue<string>("Property") : null;
+                if (!property.IsNullOrWhiteSpace())
+                    fieldControl.SetValue(DataModel!.GetEntityValue(property));
+                else
+                    fieldControl.SetValue(value);
             }
         }
+    }
 
-        private void GetFieldValue(DFLayoutField field, DFSaveStorageEntry storage, out object? entityValue)
+    private void GetFieldValue(DFLayoutField field, DFSaveStorageEntry storage, out object? entityValue)
+    {
+        var fieldControl = GetFieldControl(field);
+        if(fieldControl != null)
         {
-            var fieldControl = GetFieldControl(field);
-            if(fieldControl != null)
-            {
-                entityValue = fieldControl.GetEntityValue();
-                fieldControl.Serialize(storage);
-            }
-            else
-            {
-                entityValue = null;
-            }
+            entityValue = fieldControl.GetEntityValue();
+            fieldControl.Serialize(storage);
         }
+        else
+        {
+            entityValue = null;
+        }
+    }
 
-        public object? GetFieldValue(string fieldName)
+    public object? GetFieldValue(string fieldName)
+    {
+        var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
+        if (field is null)
         {
-            var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
-            if (field is null)
-            {
-                return null;
-            }
-            var fieldControl = GetFieldControl(field);
-            return fieldControl?.GetValue();
+            return null;
         }
+        var fieldControl = GetFieldControl(field);
+        return fieldControl?.GetValue();
+    }
 
-        public object? GetFieldData(string fieldName, string dataField)
+    public object? GetFieldData(string fieldName, string dataField)
+    {
+        var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
+        if (field is null)
         {
-            var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
-            if (field is null)
-            {
-                return null;
-            }
-            var fieldControl = GetFieldControl(field);
-            return fieldControl?.GetData(dataField);
+            return null;
         }
+        var fieldControl = GetFieldControl(field);
+        return fieldControl?.GetData(dataField);
+    }
 
-        public void SetFieldColour(string fieldName, Color? colour)
+    public void SetFieldColour(string fieldName, Color? colour)
+    {
+        var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
+        if (field is null || !borderMap.TryGetValue(field, out var border))
         {
-            var field = form.Elements.Where(x => (x as DFLayoutField)?.Name == fieldName).FirstOrDefault() as DFLayoutField;
-            if (field is null || !borderMap.TryGetValue(field, out var border))
-            {
-                return;
-            }
-            border.Background = GetItemBackgroundBrush(field, colour);
+            return;
         }
+        border.Background = GetItemBackgroundBrush(field, colour);
+    }
 
-        /// <summary>
-        /// Load values into editor; Must be called after <see cref="Initialize"/>.
-        /// </summary>
-        /// <remarks>
-        /// Resets <see cref="IsChanged"/>.
-        /// </remarks>
-        /// <param name="values">A storage object.</param>
-        public void LoadValues(DFLoadStorage values)
+    /// <summary>
+    /// Load values into editor; Must be called after <see cref="Initialize"/>.
+    /// </summary>
+    /// <remarks>
+    /// Resets <see cref="IsChanged"/>.
+    /// </remarks>
+    /// <param name="values">A storage object.</param>
+    public void LoadValues(DFLoadStorage values)
+    {
+        _changing = true;
+        InitializeEntityValues();
+        foreach (var (key, value) in values.Items())
         {
-            _changing = true;
-            InitializeEntityValues();
-            foreach (var (key, value) in values.Items())
+            if (!key.Contains('.'))
             {
-                if (!key.Contains('.'))
-                {
-                    LoadFieldValue(key, values.GetEntry(key));
-                }
+                LoadFieldValue(key, values.GetEntry(key));
             }
-            Form.EvaluateExpressions();
-            _changing = false;
-            _isChanged = false;
         }
+        Form.EvaluateExpressions();
+        _changing = false;
+        _isChanged = false;
+    }
 
-        public void InitializeEntityValues()
+    public void InitializeEntityValues()
+    {
+        _changing = true;
+        foreach (var field in form.Elements.OfType<DFLayoutField>())
         {
-            _changing = true;
-            foreach (var field in form.Elements.OfType<DFLayoutField>())
+            var property = DataModel != null ? field.GetPropertyValue<string>("Property") : null;
+            if (!property.IsNullOrWhiteSpace())
             {
-                var property = DataModel != null ? field.GetPropertyValue<string>("Property") : null;
-                if (!property.IsNullOrWhiteSpace())
+                var fieldControl = GetFieldControl(field);
+                if(fieldControl != null)
                 {
-                    var fieldControl = GetFieldControl(field);
-                    if(fieldControl != null)
-                    {
-                        fieldControl.SetValue(DataModel!.GetEntityValue(property));
-                    }
+                    fieldControl.SetValue(DataModel!.GetEntityValue(property));
                 }
             }
-            Form.EvaluateExpressions();
-            _changing = false;
-            _isChanged = false;
         }
+        Form.EvaluateExpressions();
+        _changing = false;
+        _isChanged = false;
+    }
 
-        /// <summary>
-        /// Takes values from editors and saves them to a dictionary; must be called after <see cref="Initialize"/>.
-        /// </summary>
-        /// <returns>A dictionary of <see cref="DigitalFormVariable.Code"/> -> value.</returns>
-        public DFSaveStorage SaveValues()
-        {
-            var result = new DFSaveStorage();
-            foreach (var formElement in form.Elements)
-                if (formElement is DFLayoutField field)
-                {
-                    GetFieldValue(field, result.GetEntry(field.Name), out var entityValue);
+    /// <summary>
+    /// Takes values from editors and saves them to a dictionary; must be called after <see cref="Initialize"/>.
+    /// </summary>
+    /// <returns>A dictionary of <see cref="DigitalFormVariable.Code"/> -> value.</returns>
+    public DFSaveStorage SaveValues()
+    {
+        var result = new DFSaveStorage();
+        foreach (var formElement in form.Elements)
+            if (formElement is DFLayoutField field)
+            {
+                GetFieldValue(field, result.GetEntry(field.Name), out var entityValue);
 
-                    if(DataModel != null)
-                    {
-                        var property = field.GetPropertyValue<string>("Property");
-                        if (!string.IsNullOrWhiteSpace(property))
-                            DataModel.SetEntityValue(property, entityValue);
-                    }
+                if(DataModel != null)
+                {
+                    var property = field.GetPropertyValue<string>("Property");
+                    if (!string.IsNullOrWhiteSpace(property))
+                        DataModel.SetEntityValue(property, entityValue);
                 }
+            }
 
-            return result;
-        }
+        return result;
+    }
 
-        public bool Validate(out List<string> messages)
+    public bool Validate(out List<string> messages)
+    {
+        messages = new List<string>();
+        var valid = true;
+        foreach(var formElement in form.Elements)
         {
-            messages = new List<string>();
-            var valid = true;
-            foreach(var formElement in form.Elements)
+            if(formElement is DFLayoutField field)
             {
-                if(formElement is DFLayoutField field)
+                var fieldControl = GetFieldControl(field);
+                if(fieldControl != null && !fieldControl.Validate(out var message))
                 {
-                    var fieldControl = GetFieldControl(field);
-                    if(fieldControl != null && !fieldControl.Validate(out var message))
-                    {
-                        messages.Add(message);
-                        valid = false;
-                    }
+                    messages.Add(message);
+                    valid = false;
                 }
             }
-            return valid;
         }
+        return valid;
+    }
 
-        #endregion
+    #endregion
 
-    }
 }