浏览代码

Improvements to DynamicSplitPanel
Split DynamicImagePreviewColumn to read-only and updateable versions

Frank van den Bos 2 年之前
父节点
当前提交
8d9872fc6c

+ 10 - 0
InABox.Core/Column.cs

@@ -152,6 +152,16 @@ namespace InABox.Core
             columns = new List<Column<T>>();
             columns = new List<Column<T>>();
         }
         }
 
 
+        public int IndexOf(String columnname)
+        {
+            return ColumnNames().ToList().IndexOf(columnname);
+        }
+        
+        public int IndexOf(Expression<Func<T, object>> expression)
+        {
+            return ColumnNames().ToList().IndexOf(CoreUtils.GetFullPropertyName(expression,"."));
+        }
+        
         public Columns(params Expression<Func<T, object?>>[] expressions) : this()
         public Columns(params Expression<Func<T, object?>>[] expressions) : this()
         {
         {
             foreach (var expression in expressions)
             foreach (var expression in expressions)

+ 21 - 0
InABox.Core/DataTable.cs

@@ -144,6 +144,19 @@ namespace InABox.Core
             return (ToObject(typeof(T)) as T)!;
             return (ToObject(typeof(T)) as T)!;
         }
         }
 
 
+        public T Get<T>(int col, bool usedefault = true)
+        {
+            if (col < 0 || col >= Values.Count)
+            {
+                if (usedefault)
+                    return CoreUtils.GetDefault<T>();
+                throw new Exception(string.Format("Column [{0}] does not exist!", col));
+            }
+
+            return Values[col] != null ? (T)CoreUtils.ChangeType(Values[col], typeof(T)) : CoreUtils.GetDefault<T>();
+
+        }
+        
         public T Get<T>(string columnname, bool usedefault = true)
         public T Get<T>(string columnname, bool usedefault = true)
         {
         {
             var col = GetColumn(columnname);
             var col = GetColumn(columnname);
@@ -172,6 +185,14 @@ namespace InABox.Core
             Set(colname, value);
             Set(colname, value);
         }
         }
 
 
+        public void Set<T>(int col, T value)
+        {
+            while (Values.Count <= col)
+                Values.Add(Table.Columns[Values.Count].DataType.GetDefault());
+
+            Values[col] = value;
+        }
+        
         public void Set<T>(string columnname, T value)
         public void Set<T>(string columnname, T value)
         {
         {
             var col = GetColumn(columnname);
             var col = GetColumn(columnname);

+ 71 - 56
InABox.DynamicGrid/Columns/DynamicImagePreviewColumn.cs → InABox.DynamicGrid/Columns/DynamicImageManagerColumn.cs

@@ -16,48 +16,34 @@ using Microsoft.Win32;
 
 
 namespace InABox.DynamicGrid
 namespace InABox.DynamicGrid
 {
 {
+
     public class DynamicImagePreviewColumn<T> : DynamicImageColumn
     public class DynamicImagePreviewColumn<T> : DynamicImageColumn
-        where T : Entity, IRemotable, IPersistent, new()
+        where T : BaseObject
     {
     {
+        
         private static readonly BitmapImage _preview = Resources.doc_png.AsBitmapImage();
         private static readonly BitmapImage _preview = Resources.doc_png.AsBitmapImage();
 
 
-        private static Expression<Func<T, ImageDocumentLink>> _property;
-
-        private readonly bool _canupdate;
-
-        private readonly IDynamicGrid _parent;
-
-        public DynamicImagePreviewColumn(IDynamicGrid parent, Expression<Func<T, ImageDocumentLink>> property, bool canupdate) : base(PreviewImage)
+        protected static Expression<Func<T, ImageDocumentLink>> Property { get; private set; }
+        
+        protected static string ImageIDProperty => Property != null ? CoreUtils.GetFullPropertyName(Property, ".") + ".ID" : "";
+        
+        public DynamicImagePreviewColumn(Expression<Func<T, ImageDocumentLink>> property) : base(PreviewImage)
         {
         {
-            _parent = parent;
-            _property = property;
-            _canupdate = canupdate;
+            Property = property;
             Image = PreviewImage;
             Image = PreviewImage;
             Filters = new[] { "Image Present", "Blank Image" };
             Filters = new[] { "Image Present", "Blank Image" };
             FilterRecord = DoFilterImages;
             FilterRecord = DoFilterImages;
-            ContextMenu = CreateImageMenu;
             ToolTip = CreateImageToolTip;
             ToolTip = CreateImageToolTip;
         }
         }
-
-        private static string _imageid => _property != null ? CoreUtils.GetFullPropertyName(_property, ".") + ".ID" : "";
-        private static string _imagefilename => _property != null ? CoreUtils.GetFullPropertyName(_property, ".") + ".FileName" : "";
-
+        
         private static BitmapImage PreviewImage(CoreRow arg)
         private static BitmapImage PreviewImage(CoreRow arg)
         {
         {
-            if (arg == null || arg.Get<Guid>(_imageid) == Guid.Empty)
+            if (arg == null || arg.Get<Guid>(ImageIDProperty) == Guid.Empty)
                 return null;
                 return null;
             return _preview;
             return _preview;
         }
         }
-
-        private MenuItem CreateMenu(string caption, RoutedEventHandler click)
-        {
-            var item = new MenuItem();
-            item.Header = caption;
-            item.Click += click;
-            return item;
-        }
-
-        private Bitmap LoadBitmapFromDatabase(Guid imageid)
+        
+        protected Bitmap LoadBitmapFromDatabase(Guid imageid)
         {
         {
             if (imageid == Guid.Empty)
             if (imageid == Guid.Empty)
                 return null;
                 return null;
@@ -74,7 +60,58 @@ namespace InABox.DynamicGrid
 
 
             return result;
             return result;
         }
         }
+        
+        private FrameworkElement CreateImageToolTip(DynamicActionColumn column, CoreRow arg)
+        {
+            FrameworkElement result = null;
+            var imageid = arg.Get<Guid>(ImageIDProperty);
+            if (!imageid.Equals(Guid.Empty))
+                using (new WaitCursor())
+                {
+                    var bmp = LoadBitmapFromDatabase(imageid);
+                    result = ImageToolTip(bmp?.AsBitmapImage(false));
+                }
 
 
+            return result;
+        }
+        
+        private bool DoFilterImages(CoreRow row, string[] filter)
+        {
+            var hasimage = row.Get<Guid>(ImageIDProperty) != Guid.Empty;
+            if (filter.Contains("Image Present") && hasimage)
+                return true;
+            if (filter.Contains("Blank Image") && !hasimage)
+                return true;
+            return false;
+        }
+    }
+    
+    public class DynamicImageManagerColumn<T> : DynamicImagePreviewColumn<T>
+        where T : Entity, IRemotable, IPersistent, new()
+    {
+
+
+        private readonly bool _canupdate;
+
+        private readonly IDynamicGrid _parent;
+        
+        private static string _imagefilename => Property != null ? CoreUtils.GetFullPropertyName(Property, ".") + ".FileName" : "";
+
+        public DynamicImageManagerColumn(IDynamicGrid parent, Expression<Func<T, ImageDocumentLink>> property, bool canupdate) : base(property)
+        {
+            _parent = parent;
+            _canupdate = canupdate;
+            ContextMenu = CreateImageMenu;
+        }
+        
+        private MenuItem CreateMenu(string caption, RoutedEventHandler click)
+        {
+            var item = new MenuItem();
+            item.Header = caption;
+            item.Click += click;
+            return item;
+        }
+        
         private void SaveBitmapToDatabase(CoreRow row, Guid id, string filename, Bitmap bitmap)
         private void SaveBitmapToDatabase(CoreRow row, Guid id, string filename, Bitmap bitmap)
         {
         {
             var docid = id;
             var docid = id;
@@ -110,12 +147,12 @@ namespace InABox.DynamicGrid
             }
             }
 
 
             var item = row.ToObject<T>();
             var item = row.ToObject<T>();
-            CoreUtils.SetPropertyValue(item, _imageid, docid);
+            CoreUtils.SetPropertyValue(item, ImageIDProperty, docid);
             CoreUtils.SetPropertyValue(item, _imagefilename, Path.GetFileName(filename));
             CoreUtils.SetPropertyValue(item, _imagefilename, Path.GetFileName(filename));
             new Client<T>().Save(item, "", (p, err) => { });
             new Client<T>().Save(item, "", (p, err) => { });
 
 
             // False here to prevent Refreshing and losing the selected row record
             // False here to prevent Refreshing and losing the selected row record
-            _parent.UpdateRow(row, _imageid, docid, false);
+            _parent.UpdateRow(row, ImageIDProperty, docid, false);
             _parent.UpdateRow(row, _imagefilename, Path.GetFileName(filename));
             _parent.UpdateRow(row, _imagefilename, Path.GetFileName(filename));
         }
         }
 
 
@@ -124,7 +161,7 @@ namespace InABox.DynamicGrid
             if (rows == null || rows.Length != 1)
             if (rows == null || rows.Length != 1)
                 return null;
                 return null;
 
 
-            var hasimage = rows[0].Get<Guid>(_imageid) != Guid.Empty;
+            var hasimage = rows[0].Get<Guid>(ImageIDProperty) != Guid.Empty;
             var canpaste = (_canupdate && Clipboard.ContainsData("ProductImage")) || Clipboard.ContainsImage();
             var canpaste = (_canupdate && Clipboard.ContainsData("ProductImage")) || Clipboard.ContainsImage();
             var result = new ContextMenu();
             var result = new ContextMenu();
 
 
@@ -170,7 +207,7 @@ namespace InABox.DynamicGrid
 
 
         private void SaveImage(CoreRow row)
         private void SaveImage(CoreRow row)
         {
         {
-            var imageid = row.Get<Guid>(_imageid);
+            var imageid = row.Get<Guid>(ImageIDProperty);
             if (imageid == Guid.Empty)
             if (imageid == Guid.Empty)
                 return;
                 return;
             var filename = row.Get<string>(_imagefilename);
             var filename = row.Get<string>(_imagefilename);
@@ -186,9 +223,9 @@ namespace InABox.DynamicGrid
 
 
         private void CopyImage(CoreRow row)
         private void CopyImage(CoreRow row)
         {
         {
-            var bmp = LoadBitmapFromDatabase(row.Get<Guid>(_imageid));
+            var bmp = LoadBitmapFromDatabase(row.Get<Guid>(ImageIDProperty));
             var data = new Tuple<Guid, string, Bitmap>(
             var data = new Tuple<Guid, string, Bitmap>(
-                row.Get<Guid>(_imageid),
+                row.Get<Guid>(ImageIDProperty),
                 row.Get<string>(_imagefilename),
                 row.Get<string>(_imagefilename),
                 bmp
                 bmp
             );
             );
@@ -197,7 +234,7 @@ namespace InABox.DynamicGrid
 
 
         private void PasteImage(CoreRow row)
         private void PasteImage(CoreRow row)
         {
         {
-            if (row.Get<Guid>(_imageid) != Guid.Empty)
+            if (row.Get<Guid>(ImageIDProperty) != Guid.Empty)
                 if (MessageBox.Show("Are you sure you wish to update the image for the selected items(s)?", "Update Images", MessageBoxButton.YesNo,
                 if (MessageBox.Show("Are you sure you wish to update the image for the selected items(s)?", "Update Images", MessageBoxButton.YesNo,
                         MessageBoxImage.Question) != MessageBoxResult.Yes)
                         MessageBoxImage.Question) != MessageBoxResult.Yes)
                     return;
                     return;
@@ -259,28 +296,6 @@ namespace InABox.DynamicGrid
             //_parent?.Refresh(false, false);
             //_parent?.Refresh(false, false);
         }
         }
 
 
-        private bool DoFilterImages(CoreRow row, string[] filter)
-        {
-            var hasimage = row.Get<Guid>(_imageid) != Guid.Empty;
-            if (filter.Contains("Image Present") && hasimage)
-                return true;
-            if (filter.Contains("Blank Image") && !hasimage)
-                return true;
-            return false;
-        }
-
-        private FrameworkElement CreateImageToolTip(DynamicActionColumn column, CoreRow arg)
-        {
-            FrameworkElement result = null;
-            var imageid = arg.Get<Guid>(_imageid);
-            if (!imageid.Equals(Guid.Empty))
-                using (new WaitCursor())
-                {
-                    var bmp = LoadBitmapFromDatabase(imageid);
-                    result = ImageToolTip(bmp?.AsBitmapImage(false));
-                }
 
 
-            return result;
-        }
     }
     }
 }
 }

+ 114 - 34
InABox.DynamicGrid/DynamicSplitPanel.cs

@@ -1,4 +1,7 @@
 using System;
 using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Data;
@@ -8,41 +11,46 @@ using Syncfusion.Windows.Controls.Input;
 
 
 namespace InABox.DynamicGrid
 namespace InABox.DynamicGrid
 {
 {
+    [Flags]
     public enum DynamicSplitPanelView
     public enum DynamicSplitPanelView
+    {
+        Master = 1,
+        Detail = 2,
+        Combined = 4
+    }
+
+    public enum DynamicSplitPanelAnchor
     {
     {
         Master,
         Master,
-        Detail,
-        Combined
+        Detail
     }
     }
 
 
-    public class DynamicSplitPanelChangedArgs : EventArgs
+    public class DynamicSplitPanelSettings : EventArgs
     {
     {
         public DynamicSplitPanelView View { get; set; }
         public DynamicSplitPanelView View { get; set; }
-        public double MasterWidth { get; set; }
+        public double AnchorWidth { get; set; }
         public double DetailHeight { get; set; }
         public double DetailHeight { get; set; }
     }
     }
 
 
-    public delegate void DynamicSplitPanelChanged(object sender, DynamicSplitPanelChangedArgs e);
+    public delegate void DynamicSplitPanelChanged(object sender, DynamicSplitPanelSettings e);
 
 
     public class DynamicSplitPanel : Control
     public class DynamicSplitPanel : Control
     {
     {
+        
+        public static readonly DependencyProperty AllowableViewsProperty = DependencyProperty.Register(
+            nameof(AllowableViews), 
+            typeof(DynamicSplitPanelView),
+            typeof(DynamicSplitPanel), 
+            new UIPropertyMetadata( DynamicSplitPanelView.Master | DynamicSplitPanelView.Combined | DynamicSplitPanelView.Detail ));
+        
         public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(DynamicSplitPanelView),
         public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(DynamicSplitPanelView),
             typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelView.Detail));
             typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelView.Detail));
 
 
-        //public static readonly DependencyProperty HeaderVisibilityProperty = DependencyProperty.Register("HeaderVisibility", typeof(Visibility), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
-
-        //public Visibility HeaderVisibility
-        //{
-        //    get { return (Visibility)GetValue(HeaderVisibilityProperty); }
-        //    set
-        //    {
-        //        SetValue(HeaderVisibilityProperty, value);
-        //        ConfigureScreen();
-        //    }
-        //}
-
-        public static readonly DependencyProperty MasterWidthProperty =
-            DependencyProperty.Register("MasterWidth", typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)300F));
+        public static readonly DependencyProperty AnchorProperty = DependencyProperty.Register(nameof(Anchor), typeof(DynamicSplitPanelAnchor),
+            typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelAnchor.Master));
+        
+        public static readonly DependencyProperty AnchorWidthProperty =
+            DependencyProperty.Register(nameof(AnchorWidth), typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)300F));
 
 
         public static readonly DependencyProperty MasterCaptionProperty =
         public static readonly DependencyProperty MasterCaptionProperty =
             DependencyProperty.Register("MasterCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
             DependencyProperty.Register("MasterCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
@@ -86,6 +94,27 @@ namespace InABox.DynamicGrid
         {
         {
             DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicSplitPanel), new FrameworkPropertyMetadata(typeof(DynamicSplitPanel)));
             DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicSplitPanel), new FrameworkPropertyMetadata(typeof(DynamicSplitPanel)));
         }
         }
+        
+        public DynamicSplitPanelView AllowableViews
+        {
+            get => (DynamicSplitPanelView)GetValue(AllowableViewsProperty);
+            set
+            {
+                SetValue(AllowableViewsProperty, value);
+                ConfigureScreen();
+            }
+            
+        }    
+        
+        private bool IsViewAllowed(params DynamicSplitPanelView[] views)
+        {
+            foreach (var view in views)
+            {
+                if ((AllowableViews & view) == view)
+                    return true;
+            }
+            return false;
+        }
 
 
         public DynamicSplitPanelView View
         public DynamicSplitPanelView View
         {
         {
@@ -97,12 +126,22 @@ namespace InABox.DynamicGrid
             }
             }
         }
         }
 
 
-        public double MasterWidth
+        public DynamicSplitPanelAnchor Anchor
+        {
+            get => (DynamicSplitPanelAnchor)GetValue(AnchorProperty);
+            set 
+            {
+                SetValue(AnchorProperty, value);
+                ConfigureScreen();
+            }
+        }
+        
+        public double AnchorWidth
         {
         {
-            get => (double)GetValue(MasterWidthProperty);
+            get => (double)GetValue(AnchorWidthProperty);
             set
             set
             {
             {
-                SetValue(MasterWidthProperty, value);
+                SetValue(AnchorWidthProperty, value);
                 ConfigureScreen();
                 ConfigureScreen();
             }
             }
         }
         }
@@ -181,6 +220,8 @@ namespace InABox.DynamicGrid
             Changed();
             Changed();
         }
         }
 
 
+
+
         private void ConfigureScreen()
         private void ConfigureScreen()
         {
         {
             CheckParts();
             CheckParts();
@@ -188,6 +229,7 @@ namespace InABox.DynamicGrid
             {
             {
                 if (MasterHeader != null)
                 if (MasterHeader != null)
                     MasterHeader.Content = MasterCaption;
                     MasterHeader.Content = MasterCaption;
+                
                 if (DetailsHeader != null)
                 if (DetailsHeader != null)
                     DetailsHeader.Content = DetailCaption;
                     DetailsHeader.Content = DetailCaption;
 
 
@@ -199,22 +241,41 @@ namespace InABox.DynamicGrid
 
 
                 if (Grid != null)
                 if (Grid != null)
                 {
                 {
-                    Grid.ColumnDefinitions[0].Width = View == DynamicSplitPanelView.Detail && Master != null
+                    Grid.ColumnDefinitions[0].Width = (View == DynamicSplitPanelView.Detail) 
+                                                      && (Master != null) 
+                                                      && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Master))
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         : new GridLength(0.0F, GridUnitType.Pixel);
                         : new GridLength(0.0F, GridUnitType.Pixel);
-                    Grid.ColumnDefinitions[1].Width = Master == null ? new GridLength(0.0F, GridUnitType.Pixel) :
-                        View == DynamicSplitPanelView.Master ? new GridLength(1.0F, GridUnitType.Star) :
-                        View == DynamicSplitPanelView.Detail ? new GridLength(0.0F, GridUnitType.Pixel) :
-                        new GridLength(MasterWidth, GridUnitType.Pixel);
-                    Grid.ColumnDefinitions[2].Width = View == DynamicSplitPanelView.Combined && Master != null
+                    
+                    Grid.ColumnDefinitions[1].Width = Master == null 
+                        ? new GridLength(0.0F, GridUnitType.Pixel) 
+                        : View switch { 
+                            DynamicSplitPanelView.Master => new GridLength(1.0F, GridUnitType.Star),
+                            DynamicSplitPanelView.Detail => new GridLength(0.0F, GridUnitType.Pixel),
+                            _ => Anchor == DynamicSplitPanelAnchor.Master 
+                                ? new GridLength(AnchorWidth, GridUnitType.Pixel) 
+                                : new GridLength(1.0F, GridUnitType.Star)
+                        };
+                    
+                    Grid.ColumnDefinitions[2].Width = (View == DynamicSplitPanelView.Combined) 
+                                                      && (Master != null)
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         : new GridLength(0.0F, GridUnitType.Pixel);
                         : new GridLength(0.0F, GridUnitType.Pixel);
-                    Grid.ColumnDefinitions[3].Width = View == DynamicSplitPanelView.Master
-                        ? new GridLength(0.0F, GridUnitType.Star)
-                        : new GridLength(1.0F, GridUnitType.Star);
-                    Grid.ColumnDefinitions[4].Width = View == DynamicSplitPanelView.Master
+
+                    Grid.ColumnDefinitions[3].Width = View switch
+                    {
+                        DynamicSplitPanelView.Master => new GridLength(0.0F, GridUnitType.Pixel),
+                        DynamicSplitPanelView.Detail => new GridLength(1.0F, GridUnitType.Star),
+                        _ => Anchor == DynamicSplitPanelAnchor.Detail
+                            ? new GridLength(AnchorWidth, GridUnitType.Pixel)
+                            : new GridLength(1.0F, GridUnitType.Star)
+                    };
+                        
+                    Grid.ColumnDefinitions[4].Width = (View == DynamicSplitPanelView.Master) 
+                                                      && (IsViewAllowed(DynamicSplitPanelView.Combined,DynamicSplitPanelView.Detail))
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         ? new GridLength(1.0F, GridUnitType.Auto)
                         : new GridLength(0.0F, GridUnitType.Pixel);
                         : new GridLength(0.0F, GridUnitType.Pixel);
+                    
                     Grid.RowDefinitions[0].Height =
                     Grid.RowDefinitions[0].Height =
                         Header == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
                         Header == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
                 }
                 }
@@ -232,6 +293,22 @@ namespace InABox.DynamicGrid
                         SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Star);
                         SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Star);
                     DetailSplitter.IsEnabled = SecondaryDetail != null;
                     DetailSplitter.IsEnabled = SecondaryDetail != null;
                 }
                 }
+
+
+                if (CombinedRight != null)
+                {
+                    CombinedRight.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Master)
+                        ? Visibility.Visible
+                        : Visibility.Collapsed;
+                }
+                
+                if (CombinedLeft != null)
+                {
+                    CombinedLeft.Visibility = (View == DynamicSplitPanelView.Combined) && IsViewAllowed(DynamicSplitPanelView.Detail)
+                        ? Visibility.Visible
+                        : Visibility.Collapsed;
+                }
+
             }
             }
             catch (Exception e)
             catch (Exception e)
             {
             {
@@ -241,14 +318,17 @@ namespace InABox.DynamicGrid
 
 
         private void Splitter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
         private void Splitter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
         {
         {
-            SetValue(MasterWidthProperty, Grid.ColumnDefinitions[1].ActualWidth);
+            if (Anchor == DynamicSplitPanelAnchor.Master)
+                SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[1].ActualWidth);
+            else 
+                SetValue(AnchorWidthProperty, Grid.ColumnDefinitions[3].ActualWidth);
             SetValue(DetailHeightProperty, SecondaryDetail == null ? 0.0F : DetailGrid.RowDefinitions[0].ActualHeight);
             SetValue(DetailHeightProperty, SecondaryDetail == null ? 0.0F : DetailGrid.RowDefinitions[0].ActualHeight);
             Changed();
             Changed();
         }
         }
 
 
         private void Changed()
         private void Changed()
         {
         {
-            OnChanged?.Invoke(this, new DynamicSplitPanelChangedArgs { View = View, MasterWidth = MasterWidth, DetailHeight = DetailHeight });
+            OnChanged?.Invoke(this, new DynamicSplitPanelSettings { View = View, AnchorWidth = AnchorWidth, DetailHeight = DetailHeight });
         }
         }
 
 
         public override void OnApplyTemplate()
         public override void OnApplyTemplate()

+ 4 - 4
InABox.DynamicGrid/Themes/Generic.xaml

@@ -62,12 +62,12 @@
                         <DockPanel Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Margin="0,0,2,0">
                         <DockPanel Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Margin="0,0,2,0">
 
 
                             <Button DockPanel.Dock="Top" x:Name="PART_DetailsOnly" BorderBrush="Gray"
                             <Button DockPanel.Dock="Top" x:Name="PART_DetailsOnly" BorderBrush="Gray"
-                                    BorderThickness="0.75" Margin="0" Background="WhiteSmoke" MinHeight="25"
+                                    BorderThickness="0.75,0.75,0.75,0" Margin="0" Background="WhiteSmoke" MinHeight="25"
                                     MinWidth="25">
                                     MinWidth="25">
                                 <Polygon Points="0,0 8,5, 0,10" Stroke="Gray" Fill="Silver" />
                                 <Polygon Points="0,0 8,5, 0,10" Stroke="Gray" Fill="Silver" />
                             </Button>
                             </Button>
 
 
-                            <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75" Margin="0,2,0,0"
+                            <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75,0,0.75,0.75" Margin="0,0,0,0"
                                     Background="WhiteSmoke">
                                     Background="WhiteSmoke">
                                 <Label x:Name="PART_MasterHeader"
                                 <Label x:Name="PART_MasterHeader"
                                        Content="{Binding MasterCaption, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DynamicSplitPanel}}"
                                        Content="{Binding MasterCaption, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DynamicSplitPanel}}"
@@ -165,12 +165,12 @@
                         <DockPanel Grid.Row="0" Grid.Column="4" Grid.RowSpan="2" Margin="2,0,0,0">
                         <DockPanel Grid.Row="0" Grid.Column="4" Grid.RowSpan="2" Margin="2,0,0,0">
 
 
                             <Button DockPanel.Dock="Top" x:Name="PART_MasterOnly" BorderBrush="Gray"
                             <Button DockPanel.Dock="Top" x:Name="PART_MasterOnly" BorderBrush="Gray"
-                                    BorderThickness="0.75" Margin="0" Background="WhiteSmoke" MinHeight="25"
+                                    BorderThickness="0.75,0.75,0.75,0" Margin="0" Background="WhiteSmoke" MinHeight="25"
                                     MinWidth="25">
                                     MinWidth="25">
                                 <Polygon Points="8,0 0,5, 8,10" Stroke="Gray" Fill="Silver" />
                                 <Polygon Points="8,0 0,5, 8,10" Stroke="Gray" Fill="Silver" />
                             </Button>
                             </Button>
 
 
-                            <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75" Margin="0,2,0,0"
+                            <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75,0,0.75,0.75" 
                                     Background="WhiteSmoke">
                                     Background="WhiteSmoke">
                                 <Label x:Name="PART_DetailHeader"
                                 <Label x:Name="PART_DetailHeader"
                                        Content="{Binding DetailCaption, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DynamicSplitPanel}}"
                                        Content="{Binding DetailCaption, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DynamicSplitPanel}}"