浏览代码

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

Kenric Nugteren 1 年之前
父节点
当前提交
c011e879e1

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

@@ -18,6 +18,11 @@ namespace InABox.Core
         [EditorSequence(-997)]
         [ComboLookupEditor(typeof(PropertyLookupGenerator))]
         public string Property { get; set; }
+        
+        [Caption("Read Only?")]
+        [EditorSequence(-997)]
+        [CheckBoxEditor]
+        public bool ReadOnlyProperty { get; set; }
 
         [CheckBoxEditor]
         [EditorSequence(4)]
@@ -71,6 +76,7 @@ namespace InABox.Core
         {
             Description = GetProperty(nameof(Description), "");
             Property = GetProperty(nameof(Property), "");
+            ReadOnlyProperty = GetProperty(nameof(ReadOnlyProperty), true);
             Required = GetProperty(nameof(Required), false);
             Secure = GetProperty(nameof(Secure), false);
             Retain = GetProperty(nameof(Retain), false);
@@ -82,6 +88,7 @@ namespace InABox.Core
         {
             SetProperty(nameof(Description), Description);
             SetProperty(nameof(Property), Property);
+            SetProperty(nameof(ReadOnlyProperty), ReadOnlyProperty);
             SetProperty(nameof(Required), Required);
             SetProperty(nameof(Secure), Secure);
             SetProperty(nameof(Retain), Retain);

+ 8 - 1
InABox.Core/Editors/CheckListEditor.cs

@@ -4,13 +4,20 @@ namespace InABox.Core
 {
     public class CheckListEditor : BaseComboEditor
     {
+        
+        public double ColumnWidth { get; set; }
+        
         public CheckListEditor(Type generator) : base(generator)
         {
+            ColumnWidth = 100.0;
         }
 
         protected override BaseEditor DoClone()
         {
-            return CloneBaseComboEditor();
+            var result =  CloneBaseComboEditor();
+            if (result is CheckListEditor cbe)
+                cbe.ColumnWidth = this.ColumnWidth;
+            return result;
         }
     }
 }

+ 1 - 0
InABox.Core/InABox.Core.csproj

@@ -24,6 +24,7 @@
     </ItemGroup>
     <ItemGroup>
         <PackageReference Include="ExpressiveParser" Version="3.0.1" />
+        <PackageReference Include="FluentResults" Version="3.15.2" />
         <PackageReference Include="Fody" Version="6.8.1">
             <PrivateAssets>all</PrivateAssets>
             <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

+ 30 - 2
InABox.Core/LinkedProperties.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Linq.Expressions;
+using FluentResults;
 
 namespace InABox.Core
 {
@@ -16,6 +17,31 @@ namespace InABox.Core
 
         void SetLinkedPath(string path);
     }
+    
+    // public interface IResult
+    // {
+    //     object? Value { get; set; }
+    //     bool Cancel { get; set; }
+    // }
+    //
+    // public class Result<TType> : IResult
+    // {
+    //     public TType Value { get; set; }
+    //
+    //     object? IResult.Value {
+    //         get => this.Value;
+    //         set => this.Value = (value is TType _type ? _type : default)!;
+    //     }
+    //     
+    //     public bool Cancel { get; set; }
+    //
+    //     public Result(TType value, bool cancel = false)
+    //     {
+    //         Value = value;
+    //         Cancel = cancel;
+    //     }
+    // }
+
 
     public static class LinkedProperties
     {
@@ -23,9 +49,11 @@ namespace InABox.Core
         private static readonly Dictionary<Type, List<ILinkedProperty>> _LinkedProperties = new Dictionary<Type, List<ILinkedProperty>>();
         
         public static void Register<TLinkedEntity, TEntityLink, TType>(Expression<Func<TLinkedEntity,TEntityLink>> path, Expression<Func<TEntityLink, TType>> source,
-            Expression<Func<TLinkedEntity, TType>> target)
+            Expression<Func<TLinkedEntity?, TType>> target, Func<TLinkedEntity?,TType, Result<TType>>? func = null)
+            where TLinkedEntity : class
+            where TEntityLink : class
         {
-            var map = new LinkedProperty<TLinkedEntity, TEntityLink, TType>(path, source, target);
+            var map = new LinkedProperty<TLinkedEntity, TEntityLink, TType>(path, source, target, func);
             if(!_LinkedProperties.TryGetValue(map.Type, out var props))
             {
                 props = new List<ILinkedProperty>();

+ 21 - 3
InABox.Core/LinkedProperty.cs

@@ -2,6 +2,7 @@
 using System.Linq;
 using System.Linq.Expressions;
 using System.Reflection;
+using FluentResults;
 
 namespace InABox.Core
 {
@@ -22,11 +23,17 @@ namespace InABox.Core
     }
 
     public class LinkedProperty<TLinkedEntity, TEntityLink, TType> : ILinkedProperty
+        where TLinkedEntity : class
+        where TEntityLink : class
     {
         public Type Type => typeof(TLinkedEntity);
         public String Path { get; }
+
+        private Func<TEntityLink?, TType> _source;
         public String Source { get; }
         public String Target { get; }
+
+        private readonly Func<TLinkedEntity?, TType, Result<TType>>? _func;
         
         public override string ToString()
         {
@@ -34,19 +41,30 @@ namespace InABox.Core
         }
         
         public LinkedProperty(Expression<Func<TLinkedEntity, TEntityLink>> path, 
-            Expression<Func<TEntityLink, TType>> source,
-            Expression<Func<TLinkedEntity, TType>> target)
+            Expression<Func<TEntityLink?, TType>> source,
+            Expression<Func<TLinkedEntity?, TType>> target,
+            Func<TLinkedEntity?,TType, Result<TType>>? func = null)
         {
             Path = CoreUtils.GetFullPropertyName(path, ".");
             Source = CoreUtils.GetFullPropertyName(source, ".");
             Target = CoreUtils.GetFullPropertyName(target,".");
+            _func = func;
+            _source = source.Compile();
         }
 
         public void Update(object? from, object? to)
         {
             if (from != null && to != null)
             {
-                var value = CoreUtils.GetPropertyValue(from, Source);
+                var value = _source.Invoke(from as TEntityLink);
+                //var value = CoreUtils.GetPropertyValue(from, Source);
+                if (_func != null)
+                {
+                    var result = _func(to as TLinkedEntity, value);
+                    if (!result.IsSuccess)
+                        return;
+                    value = result.Value;
+                }
                 CoreUtils.SetPropertyValue(to, Target, value);
             }
         }

+ 16 - 7
inabox.scripting/FileReader/ExcelFileReader.cs

@@ -14,9 +14,12 @@ namespace InABox.Scripting
 {
     public class ExcelFileReader : ITabularFileReader
     {
-        private IEnumerator<IRow> rows;
 
-        public Dictionary<string, int> Columns { get; set; }
+        private readonly Spreadsheet _sheet;
+        
+        private IEnumerator<IRow> _rows;
+
+        public Dictionary<string, int> Columns { get; set; } = new();
 
         [MemberNotNullWhen(false, nameof(_row))]
         public bool EndOfData { get; private set; }
@@ -25,11 +28,17 @@ namespace InABox.Scripting
 
         public ExcelFileReader(Stream stream)
         {
-            rows = new Spreadsheet(stream).GetSheet(0).RowEnumerator();
-            Columns = new Dictionary<string, int>();
-            SkipLine();
+            _sheet = new Spreadsheet(stream);
+            SelectSheet(0);
         }
 
+        public void SelectSheet(int sheet)
+        {
+            _rows = _sheet.GetSheet(sheet).RowEnumerator();
+            Columns.Clear();
+            SkipLine();
+        }
+        
         public IList<string> ReadLineValues()
         {
             var results = new List<string>();
@@ -108,10 +117,10 @@ namespace InABox.Scripting
         {
             if (!EndOfData)
             {
-                EndOfData = !rows.MoveNext();
+                EndOfData = !_rows.MoveNext();
                 if (!EndOfData)
                 {
-                    _row = rows.Current;
+                    _row = _rows.Current;
                 }
             }
             return EndOfData;

+ 3 - 1
inabox.scripting/ScriptDocument.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Data;
 using System.Drawing;
 using System.IO;
 using System.Linq;
@@ -55,7 +56,8 @@ public class ScriptDocument : INotifyPropertyChanged
             .Add(typeof(List<>).Assembly)
             .Add(typeof(Enumerable).Assembly)
             .Add(typeof(Bitmap).Assembly)
-            .Add(typeof(Expression).Assembly);
+            .Add(typeof(Expression).Assembly)
+            .Add(typeof(DataTable).Assembly);
     }
 
 

+ 12 - 4
inabox.wpf/Converters/TimeSpanToStringConverter.cs

@@ -15,10 +15,18 @@ public class TimeSpanToStringConverter : AbstractConverter<TimeSpan,String>
     
     public override string Convert(TimeSpan value)
     {
-        var result = string.IsNullOrWhiteSpace(Format) || string.Equals(Format, "hh:mm")|| string.Equals(Format, "HH:mm")
-            ? Math.Truncate(value.TotalHours).ToString("#00") + ":" + value.Minutes.ToString("D2")
-            : string.Format("{0:" + Format.Replace(":", "\\:") + "}", value);
-        return result;
+        try
+        {
+            var result = string.IsNullOrWhiteSpace(Format) || string.Equals(Format, "hh:mm")|| string.Equals(Format, "HH:mm")
+                ? Math.Truncate(value.TotalHours).ToString("#00") + ":" + value.Minutes.ToString("D2")
+                : string.Format("{0:" + Format.Replace(":", "\\:") + "}", value);
+            return result;
+        }
+        catch (Exception e)
+        {
+            return value.ToString("c");
+        }
+
     }
 
     public override TimeSpan Deconvert(string value)

+ 1 - 1
inabox.wpf/DigitalForms/Designer/Controls/DynamicFormFieldControl.cs

@@ -90,7 +90,7 @@ namespace InABox.DynamicGrid
         protected override void AfterSetControl(TField control)
         {
             base.AfterSetControl(control);
-            if (!string.IsNullOrWhiteSpace(control.Properties.Expression))
+            if (!string.IsNullOrWhiteSpace(control.Properties.Expression) || control.Properties.ReadOnlyProperty)
             {
                 IsEnabled = false;
             }

+ 48 - 14
inabox.wpf/DynamicGrid/Editors/CheckListEditor/CheckListEditorControl.cs

@@ -2,10 +2,16 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Markup;
 using System.Windows.Media;
 using InABox.Core;
+using InABox.WPF;
+using RoslynPad.Editor;
 using Syncfusion.Windows.Shared;
 using Syncfusion.Windows.Tools.Controls;
+using ItemsPanelTemplate = System.Windows.Controls.ItemsPanelTemplate;
 
 namespace InABox.DynamicGrid
 {
@@ -15,6 +21,7 @@ namespace InABox.DynamicGrid
         static CheckListEditorControl()
         {
             //DynamicEditorControlFactory.Register<CheckListEditorControl, CheckListEditor>();
+            
         }
         
         private SolidColorBrush _color;
@@ -34,11 +41,8 @@ namespace InABox.DynamicGrid
         public override void Configure()
         {
             if (EditorDefinition is not CheckListEditor editor) return;
-
-            Width = editor.LookupWidth;
-            Editor.IsEnabled = false;
-            Editor.Background = Brushes.WhiteSmoke;
-
+            Editor.ItemsPanel = GetItemsPanelTemplate(editor.Width);
+            Editor.ItemContainerStyle = GetItemsContainerStyle(editor.ColumnWidth);
             Host.LoadLookups(this);
         }
 
@@ -61,20 +65,50 @@ namespace InABox.DynamicGrid
             SetupCheckListBox();
         }
 
+        private class WidthConverter : AbstractConverter<double, double>
+        {
+            public CheckListEditorControl Parent { get; set; }
+            
+            public override double Convert(double value)
+            {
+                return value - 10.0;
+            }
+        }
+        
+        private ItemsPanelTemplate? GetItemsPanelTemplate(double width)
+        {
+	        FrameworkElementFactory fc = new FrameworkElementFactory(typeof(WrapPanel));
+            var binding = new Binding()
+            {
+                RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(CheckListBox), 1),
+                Path = new PropertyPath(nameof(ActualWidth)),
+                Converter = new WidthConverter() { Parent = this }
+            };
+            fc.SetBinding(WidthProperty,binding);
+            //fc.SetValue(BackgroundProperty, new SolidColorBrush(Colors.LightBlue));
+	        ItemsPanelTemplate ipt = new ItemsPanelTemplate(fc);
+	        return ipt;
+        }
+
+        private Style? GetItemsContainerStyle(double width)
+        {
+            var style = new Style(typeof(CheckListBoxItem));                
+            style.Setters.Add(new Setter {Property = WidthProperty, Value = width});
+            //style.Setters.Add(new Setter {Property = BackgroundProperty, Value = new SolidColorBrush(Colors.Red)});
+            return style;
+        }
+        
+        
         protected override FrameworkElement CreateEditor()
         {
-            MinHeight = 50;
+            
             Editor = new CheckListBox
             {
-                VerticalAlignment = VerticalAlignment.Stretch,
-                VerticalContentAlignment = VerticalAlignment.Top,
-                HorizontalAlignment = HorizontalAlignment.Stretch,
-                //SelectedItemBackground = Brushes.Transparent,
-                //Foreground = Brushes.Black
                 DisplayMemberPath = "Value",
-                SelectedValuePath = "Key"
+                SelectedValuePath = "Key",
+                HorizontalAlignment = HorizontalAlignment.Stretch
             };
-            SkinStorage.SetVisualStyle(Editor, "Metro");
+            //SkinStorage.SetVisualStyle(Editor, "Metro");
             Editor.SelectionChanged += (o, e) =>
             {
                 if (!bLoading)
@@ -85,7 +119,7 @@ namespace InABox.DynamicGrid
 
         public override int DesiredWidth()
         {
-            return 150;
+            return int.MaxValue;
         }
 
         protected override Dictionary<string, bool> RetrieveValue()

+ 4 - 1
inabox.wpf/DynamicGrid/ScriptEditor.xaml.cs

@@ -117,7 +117,10 @@ namespace InABox.DynamicGrid
             bChanged = false;
         }
 
-        public string Script => Roslyn.Text;
+        public string Script
+        {
+            get => new String(Roslyn.Text);
+        }
 
         public Dictionary<string, string[]> Snippets
         {