Browse Source

Fixed DynamicTree Editing
Addec xTextbox Placeholder Behaviour
Added CodePopuopEditor to DynamicGrid

frogsoftware 1 year ago
parent
commit
5058c61027

+ 2 - 0
InABox.Core/Classes/Document/Document.cs

@@ -51,6 +51,8 @@ namespace InABox.Core
         {
             base.Init();
             Data = new byte[] { };
+            FileName = "";
+            CRC = "";
         }
 
         public override string ToString()

+ 7 - 0
InABox.Core/Classes/Document/DocumentLink.cs

@@ -24,5 +24,12 @@ namespace InABox.Core
         {
             return FileName;
         }
+
+        protected override void Init()
+        {
+            base.Init();
+            FileName = "";
+            CRC = "";
+        }
     }
 }

+ 10 - 0
InABox.Core/Column.cs

@@ -149,12 +149,22 @@ namespace InABox.Core
             var result = Activator.CreateInstance(type);
             return (result as IColumns)!;
         }
+        
         public static IColumns Create(Type concrete)
         {
             var type = typeof(Columns<>).MakeGenericType(concrete);
             var result = Activator.CreateInstance(type) as IColumns;
             return result!;
         }
+        
+        public static IColumns Create(Type concrete, params String[] columns)
+        {
+            var type = typeof(Columns<>).MakeGenericType(concrete);
+            var result = (IColumns)Activator.CreateInstance(type);
+            foreach (var column in columns)
+                result.Add(column);
+            return result;
+        }
     }
 
     public class Columns<T> : IColumns

+ 9 - 0
InABox.Core/Filter.cs

@@ -326,6 +326,15 @@ namespace InABox.Core
             var type = typeof(Filter<>).MakeGenericType(concrete);
             return (Activator.CreateInstance(type, property) as IFilter)!;
         }
+
+        public static IFilter Create(Type concrete, string property, Operator op, object value)
+        {
+            var type = typeof(Filter<>).MakeGenericType(concrete);
+            var result = (Activator.CreateInstance(type, property) as IFilter)!;
+            result.Operator = op;
+            result.Value = value;
+            return result;
+        }
     }
 
     public interface IFilter2<T>

+ 187 - 0
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -12,6 +12,7 @@ using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
+using System.Windows.Forms.VisualStyles;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
@@ -28,6 +29,7 @@ using Syncfusion.UI.Xaml.Grid.Helpers;
 using Syncfusion.Windows.Shared;
 using Brush = System.Windows.Media.Brush;
 using Color = System.Drawing.Color;
+using Columns = InABox.Core.Columns;
 using DataColumn = System.Data.DataColumn;
 using DataRow = System.Data.DataRow;
 using FilterElement = Syncfusion.UI.Xaml.Grid.FilterElement;
@@ -39,6 +41,7 @@ using Image = System.Windows.Controls.Image;
 using RowColumnIndex = Syncfusion.UI.Xaml.ScrollAxis.RowColumnIndex;
 using SolidColorBrush = System.Windows.Media.SolidColorBrush;
 using String = System.String;
+using VerticalAlignment = System.Windows.VerticalAlignment;
 using VirtualizingCellsControl = Syncfusion.UI.Xaml.Grid.VirtualizingCellsControl;
 
 namespace InABox.DynamicGrid
@@ -1190,6 +1193,28 @@ namespace InABox.DynamicGrid
             
         }
 
+        
+        private void UpdateData(Dictionary<String,object> changes)
+        {
+            if (!SelectedRows.Any())
+                return;
+            
+            var iRow = SelectedRows.First().Index; //e.RowColumnIndex.RowIndex - (HasOption(DynamicGridOptions.FilterRows) ? 2 : 1);
+            if (DataGridItems is null || iRow > DataGridItems.Rows.Count)
+                return;
+
+            var updates = new Dictionary<CoreColumn, object>();
+            foreach (var key in changes.Keys)
+            {
+                var colno = DataGridItems.Columns.IndexOf(key);
+                var column = Data.Columns[colno];
+                updates[column] = changes[key];
+            }
+            
+            UpdateData(updates);
+            
+        }
+        
         private void UpdateData(String mappedname)
         {
             if (!SelectedRows.Any())
@@ -1951,6 +1976,8 @@ namespace InABox.DynamicGrid
                         newcol = imgcol;
                         filtering = false;
                     }
+                    
+                    
                     else if (prop.Editor is PopupEditor pEditor)
                     {
                         
@@ -2052,6 +2079,131 @@ namespace InABox.DynamicGrid
                         newcol = templatecolumn;
 
                     }
+
+                    
+                    else if (prop.Editor is CodePopupEditor cpEditor)
+                    {
+                        var prefix = String.Join(".", column.ColumnName.Split('.').Reverse().Skip(1).Reverse());
+
+                        var colname = String.IsNullOrWhiteSpace(cpEditor.CodeColumn)
+                            ? CoreUtils.PropertyList(cpEditor.Type, p => p.GetEditor() is UniqueCodeEditor)
+                                .FirstOrDefault()?.Name ?? ""
+                            : cpEditor.CodeColumn;
+
+                        var codecolname = String.IsNullOrWhiteSpace(prefix)
+                            ? colname
+                            : $"{prefix}.{colname}";
+                        codecolname = codecolname.Replace('.', '_');
+                        
+                        var templatecolumn = new GridTemplateColumn();
+                        templatecolumn.CellTemplate = TemplateGenerator.CreateDataTemplate
+                        (
+                            () =>
+                            {
+                                var result = new Label();
+                                result.SetBinding(Label.ContentProperty, new Binding(codecolname));
+                                result.VerticalContentAlignment = VerticalAlignment.Center;
+                                return result;
+                            }
+                        );
+                        templatecolumn.EditTemplate = TemplateGenerator.CreateDataTemplate
+                        (
+                            () =>
+                            {
+                                if (IsDirectEditMode())
+                                {
+                                    var result = new Grid();
+                                    result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star)});
+                                    result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto)});
+                                    
+                                    var textbox = new TextBox();
+                                    textbox.CharacterCasing = CharacterCasing.Upper;
+                                    textbox.SetBinding(TextBox.TextProperty, new Binding(codecolname));
+                                    textbox.SetValue(Grid.ColumnProperty, 0);
+                                    textbox.SetValue(Grid.ColumnSpanProperty, 2);
+                                    textbox.Tag = false;
+                                    textbox.Padding = new Thickness(2, 0, 0, 0);
+                                    textbox.VerticalContentAlignment = VerticalAlignment.Center;
+                                    textbox.PreviewTextInput += (sender, args) => textbox.Tag = true;
+                                    textbox.SetValue(FocusManagerHelper.FocusedElementProperty, true);
+                                    textbox.TextChanged += (sender, args) =>
+                                    {
+                                        if (Equals(textbox.Tag, false))
+                                            textbox.SelectAll();
+                                    };
+
+                                    //textbox.GotFocus += (sender, args) => textbox.SelectAll(); 
+                                    textbox.LostFocus += (sender, args) =>
+                                    {
+                                        if (sender is TextBox { Tag: true } box &&
+                                            (sender as FrameworkElement)?.DataContext is DataRowView view)
+                                        {
+                                            if (String.IsNullOrWhiteSpace(box.Text))
+                                            {
+                                                UpdateCodePopupColumnValue(
+                                                    templatecolumn,
+                                                    Guid.Empty,
+                                                    codecolname,
+                                                    "",
+                                                    view);
+                                            }
+                                            else
+                                            {
+                                                var lookup = ClientFactory.CreateClient(cpEditor.Type).Query(
+                                                    Filter.Create(cpEditor.Type, colname, Operator.BeginsWith,
+                                                        box.Text),
+                                                    Columns.Create(cpEditor.Type, "ID", colname),
+                                                    null
+                                                );
+                                                if (lookup.Rows.Count == 1)
+                                                {
+                                                    UpdateCodePopupColumnValue(
+                                                        templatecolumn,
+                                                        lookup.Rows[0].Get<Guid>("ID"),
+                                                        codecolname,
+                                                        lookup.Rows[0].Get<String>(colname),
+                                                        view);
+                                                }
+                                                else
+                                                    PopupCodeList(sender, templatecolumn, cpEditor, colname,
+                                                        codecolname);
+                                            }
+                                        }
+
+                                    };
+                                    result.Children.Add(textbox);
+                                    
+                                    var button = new Button();
+                                    button.Content = "..";
+                                    button.Width = 25;
+                                    button.SetValue(Grid.ColumnProperty, 1);
+                                    button.Margin = new Thickness(1);
+                                    button.BorderThickness = new Thickness(0.75, 0, 0, 0);
+                                    button.Click += (sender, args) =>
+                                    {
+                                        PopupCodeList(sender, templatecolumn, cpEditor, colname, codecolname);
+                                    };
+                                    result.Children.Add(button);
+                                    
+                                    return result;
+                                }
+                                else
+                                {
+                                    var result = new Label();
+                                    result.SetBinding(Label.ContentProperty, new Binding(codecolname));
+                                    result.VerticalContentAlignment = VerticalAlignment.Center;
+                                    return result;
+                                }
+                            }
+                        );
+                        templatecolumn.SetCellBoundValue = false;
+
+                        newcol = templatecolumn;
+
+                    }
+
+                    
+                    
                     else if (prop.Editor is ILookupEditor lookupEditor)
                     {
                         var lookupcol = new GridComboBoxColumn();
@@ -2200,6 +2352,41 @@ namespace InABox.DynamicGrid
             ResizeColumns(DataGrid, DataGrid.ActualWidth - 2, DataGrid.ActualHeight - 2);
         }
 
+        private void PopupCodeList(object sender, GridTemplateColumn col, CodePopupEditor cpEditor, string colname, string codecolname)
+        {
+            if ((sender as FrameworkElement)?.DataContext is DataRowView view)
+            {
+                var id = view[col.MappingName];
+                if (id is Guid)
+                {
+                    var list = new PopupList(
+                        cpEditor.Type,
+                        (Guid)id,
+                        new String[] { colname }
+                    );
+                    list.OnDefineFilter += type =>
+                        LookupFactory.DefineFilter(cpEditor.Type, typeof(T),
+                            new T[] { inplaceeditor });
+                    if (list.ShowDialog() == true)
+                        UpdateCodePopupColumnValue(col, list.ID, codecolname, list.OtherValues[colname], view);
+                }
+            }
+        }
+
+        private void UpdateCodePopupColumnValue(GridTemplateColumn col, Guid value, string codecolname, object? code, DataRowView view)
+        {
+            
+            UpdateData(new Dictionary<String, object>()
+            {
+                { col.MappingName, value },
+                { codecolname, code ?? DBNull.Value }
+            });
+            DataGrid.SelectionController.CurrentCellManager.EndEdit();
+            //view[col.MappingName] = value;
+            //UpdateData(col.MappingName);
+            //view[codecolname] = code ?? DBNull.Value;
+        }
+
         private void ApplyFilterStyle(GridColumn column, bool filtering, bool isactioncolumn)
         {
             var filterstyle = new Style();

+ 5 - 0
inabox.wpf/DynamicGrid/DynamicTreeView.cs

@@ -394,6 +394,11 @@ namespace InABox.DynamicGrid
         protected virtual bool DoEditItem(T item)
         {
             var form = new DynamicEditorForm(typeof(T));
+            form.OnEditorValueChanged += (sender, name, value) =>
+            {
+                CoreUtils.SetPropertyValue(item, name, value);
+                return new Dictionary<string, object?>();
+            };
             form.Items = new T[] { item };
             return form.ShowDialog() == true;
         }

+ 1 - 0
inabox.wpf/ImageUtils.cs

@@ -819,6 +819,7 @@ namespace InABox.WPF
             var rendered = new List<byte[]>();
 
             PdfLoadedDocument loadeddoc = new PdfLoadedDocument(pdfData);
+            loadeddoc.FlattenAnnotations();
             Bitmap[] images = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1);
 
             var jpgEncoder = GetEncoder(ImageFormat.Jpeg)!;

+ 224 - 0
inabox.wpf/WPFUtils.cs

@@ -1,9 +1,16 @@
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Drawing;
+using System.Globalization;
 using System.Windows;
 using System.Windows.Controls;
+using System.Windows.Input;
 using System.Windows.Media;
+using InABox.Core;
+using Microsoft.Xaml.Behaviors;
+using Brush = System.Windows.Media.Brush;
+using FontStyle = System.Windows.FontStyle;
 using Image = System.Windows.Controls.Image;
 
 namespace InABox.WPF
@@ -233,4 +240,221 @@ namespace InABox.WPF
 
         #endregion
     }
+
+    public class TextBoxPlaceholderBehaviour : Behavior<TextBox>
+    {
+        
+        public static readonly DependencyProperty TextProperty =
+            DependencyProperty.Register(
+                nameof(Text),
+                typeof(String),
+                typeof(TextBoxPlaceholderBehaviour),
+                new PropertyMetadata(""));
+
+        public String Text
+        {
+            get => (String)GetValue(TextProperty);
+            set
+            {
+                SetValue(TextProperty, value);
+                UpdateAssociatedObject();
+            }
+        }
+        
+        public static readonly DependencyProperty TextColorProperty =
+            DependencyProperty.Register(
+                nameof(TextColor),
+                typeof(System.Windows.Media.Color),
+                typeof(TextBoxPlaceholderBehaviour),
+                new PropertyMetadata(Colors.Gray));
+
+        public System.Windows.Media.Color TextColor
+        {
+            get => (System.Windows.Media.Color)GetValue(TextColorProperty);
+            set
+            {
+                SetValue(TextColorProperty, value);
+                UpdateAssociatedObject();
+            }
+        }
+        
+        private readonly PropertyDescriptor _propertyDescriptor = 
+            DependencyPropertyDescriptor.FromProperty(TextBox.BackgroundProperty, typeof(TextBox));
+        
+        private Brush? _originalBackground;
+        private Brush? _placeholderBackground;
+        
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+
+            // Store the Background that has been set on the Text Box (usu through XAML)
+            _originalBackground = AssociatedObject.Background;
+            
+            // Start Monitoring changes to the Associated object Background property
+            _propertyDescriptor.AddValueChanged(AssociatedObject, OnBackgroundChanged);
+            
+            AssociatedObject.TextChanged += OnTextChanged;
+            AssociatedObject.SizeChanged += OnSizeChanged;
+            
+            UpdateAssociatedObject();
+        }
+        
+        protected override void OnDetaching()
+        {
+            AssociatedObject.SizeChanged -= OnSizeChanged;
+            AssociatedObject.TextChanged -= OnTextChanged;
+
+            _propertyDescriptor?.RemoveValueChanged(AssociatedObject,OnBackgroundChanged);
+
+            AssociatedObject.Background = _originalBackground;
+            
+            base.OnDetaching();
+        }
+        
+        
+        private void OnBackgroundChanged(object? sender, EventArgs e)
+        {
+            // Update the Saved Background (usu a color, but might not be?)
+            _originalBackground = AssociatedObject.Background;
+            _placeholderBackground = null;
+            UpdateAssociatedObject();
+        }
+
+        private void OnTextChanged(object sender, TextChangedEventArgs e)
+        {
+            UpdateAssociatedObject();
+        }
+
+        private void SetBackground(Brush? brush)
+        {
+            _propertyDescriptor.RemoveValueChanged(AssociatedObject, OnBackgroundChanged);
+            AssociatedObject.Background = brush;
+            _propertyDescriptor.AddValueChanged(AssociatedObject, OnBackgroundChanged);
+        }
+        
+        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            _placeholderBackground = null;
+            UpdateAssociatedObject();
+        }
+        
+        private Brush CreatePlaceholder()
+        {
+            return new VisualBrush()
+            {
+                Visual = new Label()
+                {
+                    Content = Text,
+                    Margin = new Thickness(0),
+                    Padding = new Thickness(4, 0, 2, 0),
+                    HorizontalAlignment = HorizontalAlignment.Stretch,
+                    VerticalAlignment = VerticalAlignment.Stretch,
+                    HorizontalContentAlignment = AssociatedObject.HorizontalContentAlignment,
+                    VerticalContentAlignment = AssociatedObject.VerticalContentAlignment,
+                    FontFamily = AssociatedObject.FontFamily,
+                    FontStretch = AssociatedObject.FontStretch,
+                    FontSize = AssociatedObject.FontSize,
+                    FontWeight = AssociatedObject.FontWeight,
+                    FontStyle = FontStyles.Italic,
+                    Background = _originalBackground?.Clone(),
+                    Foreground = new SolidColorBrush(TextColor),
+                    Width = AssociatedObject.ActualWidth,
+                    Height = AssociatedObject.ActualHeight
+                },
+                Stretch = Stretch.None,
+                TileMode = TileMode.None,
+                AlignmentX = AlignmentX.Left,
+                AlignmentY = AlignmentY.Center
+            };
+        }
+        
+        private void UpdateAssociatedObject()
+        {
+            if (String.IsNullOrWhiteSpace(AssociatedObject.Text) && _placeholderBackground == null)
+            {
+                _placeholderBackground = CreatePlaceholder();
+                SetBackground(_placeholderBackground);
+            }
+            else if (!String.IsNullOrWhiteSpace(AssociatedObject.Text) && _placeholderBackground != null)
+            { 
+                _placeholderBackground = null;
+                SetBackground(_originalBackground);
+            }
+        }
+    }
+
+    // public class TextBoxPlaceholderBehaviour : Behavior<TextBox>
+    // {
+    //     
+    //     public static readonly DependencyProperty TextProperty =
+    //         DependencyProperty.Register(
+    //             nameof(Text), 
+    //             typeof(String), 
+    //             typeof(TextBoxPlaceholderBehaviour), 
+    //             new PropertyMetadata(""));
+    //     
+    //
+    //     public String Text
+    //     {
+    //         get => (String)GetValue(TextProperty);
+    //         set => SetValue(TextProperty, value);
+    //     }
+    //     
+    //     protected override void OnAttached()
+    //     {
+    //         base.OnAttached();
+    //         AssociatedObject.GotFocus += AssociatedObjectOnGotFocus;
+    //         AssociatedObject.LostFocus += AssociatedObjectOnLostFocus;
+    //     }
+    //
+    //     protected override void OnDetaching()
+    //     {
+    //         AssociatedObject.GotFocus -= AssociatedObjectOnGotFocus;
+    //         AssociatedObject.LostFocus -= AssociatedObjectOnLostFocus;
+    //         base.OnDetaching();
+    //     }
+    //
+    //     private void AssociatedObjectOnGotFocus(object sender, RoutedEventArgs e)
+    //     {
+    //         if (String.Equals(AssociatedObject.Text, Text))
+    //         {
+    //             AssociatedObject.Text = "";
+    //             AssociatedObject.Foreground = new SolidColorBrush(Colors.Black);
+    //         }
+    //     }
+    //
+    //     private void AssociatedObjectOnLostFocus(object sender, RoutedEventArgs e)
+    //     {
+    //         if (String.IsNullOrWhiteSpace(AssociatedObject.Text))
+    //         {
+    //             AssociatedObject.Text = Text;
+    //             AssociatedObject.Foreground = new SolidColorBrush(Colors.Gray);
+    //         }
+    //     }
+    // }
+    
+    public class TextBoxEnterAsTabBehavior :
+        Behavior<TextBox>
+    {
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+            AssociatedObject.PreviewKeyDown += AssociatedObjectOnPreviewKeyDown;
+        }
+
+        protected override void OnDetaching()
+        {
+            AssociatedObject.PreviewKeyDown -= AssociatedObjectOnPreviewKeyDown;
+            base.OnDetaching();
+        }
+
+        private void AssociatedObjectOnPreviewKeyDown(object sender, KeyEventArgs args)
+        {
+            if (args.Key != Key.Enter) { return; }
+
+            args.Handled = true;
+            AssociatedObject.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
+        }
+    }
 }