瀏覽代碼

More WPF utility functions, for stlyes and converters

Kenric Nugteren 1 年之前
父節點
當前提交
0719c73eeb

+ 4 - 1
inabox.wpf/Converters/AbstractConverter.cs

@@ -21,13 +21,16 @@ public class UtilityConverterEventArgs : EventArgs
 
 
 public delegate void UtilityCoverterEvent(object sender, UtilityConverterEventArgs args);
 public delegate void UtilityCoverterEvent(object sender, UtilityConverterEventArgs args);
 
 
+public interface IValueConverter<TIn, TOut> : IValueConverter
+{
+}
 
 
 // Freezable is a way that might allow us to pass in a DataContext (ie Viewmodel) 
 // Freezable is a way that might allow us to pass in a DataContext (ie Viewmodel) 
 // to static resources with XAML.  Not yet tested, kept for reference
 // to static resources with XAML.  Not yet tested, kept for reference
 // The uncertain bit is the DependencyProperty "typeof(IValueConverter)" - this
 // The uncertain bit is the DependencyProperty "typeof(IValueConverter)" - this
 // might not do what we want, as I suspect it might require a concrete type?
 // might not do what we want, as I suspect it might require a concrete type?
 // Ref: https://thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
 // Ref: https://thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
-public abstract class AbstractConverter<TIn, TOut> : /*Freezable, */ IValueConverter
+public abstract class AbstractConverter<TIn, TOut> : /*Freezable, */ IValueConverter<TIn, TOut>
 {
 {
 
 
     public event UtilityCoverterEvent? Converting;
     public event UtilityCoverterEvent? Converting;

+ 3 - 2
inabox.wpf/Converters/FuncConverter.cs

@@ -1,4 +1,5 @@
-using System;
+using InABox.WPF;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
 using System.Linq;
 using System.Linq;
@@ -8,7 +9,7 @@ using System.Windows.Data;
 
 
 namespace InABox.Wpf;
 namespace InABox.Wpf;
 
 
-public class FuncConverter<TIn, TOut>(Func<TIn, TOut> convert, Func<TOut, TIn>? convertBack) : IValueConverter
+public class FuncConverter<TIn, TOut>(Func<TIn, TOut> convert, Func<TOut, TIn>? convertBack = null) : IValueConverter<TIn, TOut>
 {
 {
     public Func<TIn, TOut> ConvertFunc { get; set; } = convert;
     public Func<TIn, TOut> ConvertFunc { get; set; } = convert;
 
 

+ 26 - 4
inabox.wpf/DynamicGrid/Columns/DynamicTextColumn.cs

@@ -1,4 +1,5 @@
 using System;
 using System;
+using System.Linq.Expressions;
 using InABox.Core;
 using InABox.Core;
 namespace InABox.DynamicGrid;
 namespace InABox.DynamicGrid;
 
 
@@ -6,18 +7,22 @@ public class DynamicTextColumn : DynamicActionColumn
 {
 {
     public delegate object GetTextDelegate(CoreRow? row);
     public delegate object GetTextDelegate(CoreRow? row);
 
 
-    public GetTextDelegate Text { get; private set; }
+    public GetTextDelegate Text { get; protected set; }
         
         
     public Alignment Alignment { get; set; }
     public Alignment Alignment { get; set; }
     
     
     public string? Format { get; set; }
     public string? Format { get; set; }
-        
-    public DynamicTextColumn(GetTextDelegate text, ActionDelegate? action = null)
+
+    protected DynamicTextColumn()
     {
     {
         Alignment = Alignment.MiddleCenter;
         Alignment = Alignment.MiddleCenter;
+        VerticalHeader = false;
+    }
+        
+    public DynamicTextColumn(GetTextDelegate text, ActionDelegate? action = null) : this()
+    {
         Text = text;
         Text = text;
         Action = action;
         Action = action;
-        VerticalHeader = false;
     }
     }
 
 
     public override object? Data(CoreRow? row)
     public override object? Data(CoreRow? row)
@@ -27,4 +32,21 @@ public class DynamicTextColumn : DynamicActionColumn
             return String.Format($"{{0:{Format}}}", result);
             return String.Format($"{{0:{Format}}}", result);
         return result;
         return result;
     }
     }
+}
+
+public class DynamicTextColumn<T> : DynamicTextColumn
+{
+    public Expression<Func<T, object>> Property { get; set; }
+
+    public DynamicTextColumn(Expression<Func<T, object>> property, ActionDelegate? action = null)
+    {
+        Text = GetText;
+        Action = action;
+        Property = property;
+    }
+
+    private object GetText(CoreRow? row)
+    {
+        return row?.Get(Property) ?? "";
+    }
 }
 }

+ 147 - 41
inabox.wpf/WPFUtils.cs

@@ -31,6 +31,115 @@ public class FuncTemplateSelector : DataTemplateSelector
 
 
 public static class WPFUtils
 public static class WPFUtils
 {
 {
+    public static Style AddSetter(this Style style, DependencyProperty property, object value)
+    {
+        style.Setters.Add(new Setter(property, value));
+        return style;
+    }
+    public static DataTrigger AddSetter(this DataTrigger trigger, DependencyProperty property, object value)
+    {
+        trigger.Setters.Add(new Setter(property, value));
+        return trigger;
+    }
+    public static DataTrigger AddDataTrigger(this Style style)
+    {
+        var trigger = new DataTrigger();
+        style.Triggers.Add(trigger);
+        return trigger;
+    }
+    public static DataTrigger AddDataTrigger(this Style style, Binding binding, object value)
+    {
+        var trigger = new DataTrigger() { Binding = binding, Value = value };
+        style.Triggers.Add(trigger);
+        return trigger;
+    }
+
+    public static SolidColorBrush ToBrush(this System.Windows.Media.Color color)
+    {
+        return new SolidColorBrush(color);
+    }
+
+    #region Binding
+
+    public static Binding CreateBinding<T, TProperty>(
+        T source,
+        Expression<Func<T, TProperty>> expression,
+        IValueConverter? converter,
+        string? format)
+    {
+        return new Binding(CoreUtils.GetFullPropertyName(expression, "_"))
+        {
+            Source = source,
+            Converter = converter,
+            StringFormat = format
+        };
+    }
+
+    public static Binding CreateBinding<T, TProperty>(
+        Expression<Func<T, TProperty>> expression, 
+        IValueConverter? converter,
+        BindingMode mode,
+        string? format)
+    {
+        return new Binding(CoreUtils.GetFullPropertyName(expression, "_"))
+        {
+            Converter = converter,
+            StringFormat = format,
+            Mode = mode
+        };
+    }
+
+    public static DataTrigger Bind<T, TProperty, TValue>(
+        this DataTrigger trigger,
+        T source,
+        Expression<Func<T, TProperty>> expression,
+        TValue value,
+        IValueConverter<TProperty, TValue>? converter,
+        string? format = null)
+    {
+        trigger.Binding = CreateBinding(source, expression, converter, format);
+        trigger.Value = value;
+        return trigger;
+    }
+    public static DataTrigger Bind<T, TProperty, TValue>(
+        this DataTrigger trigger,
+        Expression<Func<T, TProperty>> expression, 
+        TValue value,
+        IValueConverter<TProperty, TValue>? converter,
+        BindingMode mode = BindingMode.Default,
+        string? format = null)
+    {
+        trigger.Binding = CreateBinding(expression, converter, mode, format);
+        trigger.Value = value;
+        return trigger;
+    }
+
+    public static DataTrigger Bind<T, TProperty>(
+        this DataTrigger trigger,
+        T source,
+        Expression<Func<T, TProperty>> expression,
+        TProperty value,
+        IValueConverter? converter = null,
+        string? format = null)
+    {
+        trigger.Binding = CreateBinding(source, expression, converter, format);
+        trigger.Value = value;
+        return trigger;
+    }
+
+    public static DataTrigger Bind<T, TProperty>(
+        this DataTrigger trigger,
+        Expression<Func<T, TProperty>> expression, 
+        TProperty value,
+        IValueConverter? converter = null,
+        BindingMode mode = BindingMode.Default,
+        string? format = null)
+    {
+        trigger.Binding = CreateBinding(expression, converter, mode, format);
+        trigger.Value = value;
+        return trigger;
+    }
+
     public static void Bind<T, TProperty>(
     public static void Bind<T, TProperty>(
         this FrameworkElement element,
         this FrameworkElement element,
         DependencyProperty property,
         DependencyProperty property,
@@ -41,12 +150,7 @@ public static class WPFUtils
     {
     {
         element.SetBinding(
         element.SetBinding(
             property,
             property,
-            new Binding(CoreUtils.GetFullPropertyName(expression, "_"))
-            {
-                Source = source,
-                Converter = converter,
-                StringFormat = format
-            }
+            CreateBinding(source, expression, converter, format)
         );
         );
     }
     }
 
 
@@ -60,16 +164,13 @@ public static class WPFUtils
     {
     {
         element.SetBinding(
         element.SetBinding(
             property,
             property,
-            new Binding(CoreUtils.GetFullPropertyName(expression, "_"))
-            {
-                Converter = converter,
-                StringFormat = format,
-                Mode = mode
-            }
+            CreateBinding(expression, converter, mode, format)
         );
         );
     }
     }
-    
-    
+
+    #endregion
+
+
     public static T? FindLogicalParent<T>(this DependencyObject dependencyObject)
     public static T? FindLogicalParent<T>(this DependencyObject dependencyObject)
         where T : DependencyObject
         where T : DependencyObject
     {
     {
@@ -81,6 +182,37 @@ public static class WPFUtils
         return parent as T;
         return parent as T;
     }
     }
 
 
+    public static IEnumerable<T> FindVisualChildren<T>(this DependencyObject depObj)
+    {
+        if (depObj != null)
+            //ContentControl cc = depObj as ContentControl;
+            //if (cc != null)
+            //{
+            //    if (cc.Content == null)
+            //        yield return null;
+            //    if (cc.Content is T)
+            //        yield return cc.Content as T;
+            //    foreach (var child in FindVisualChildren<T>(cc.Content as DependencyObject))
+            //        yield return child;
+            //}
+            //else
+            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
+            {
+                var child = VisualTreeHelper.GetChild(depObj, i);
+                if (child is null)
+                    continue;
+
+                if (child is T t)
+                    yield return t;
+
+                foreach (var childOfChild in FindVisualChildren<T>(child))
+                    yield return childOfChild;
+            }
+    }
+
+
+    #region Grid Children
+
     public static int GetRow(this Grid grid, DependencyObject dependencyObject)
     public static int GetRow(this Grid grid, DependencyObject dependencyObject)
     {
     {
         while (true)
         while (true)
@@ -147,33 +279,7 @@ public static class WPFUtils
         return grid;
         return grid;
     }
     }
 
 
-    public static IEnumerable<T> FindVisualChildren<T>(this DependencyObject depObj)
-    {
-        if (depObj != null)
-            //ContentControl cc = depObj as ContentControl;
-            //if (cc != null)
-            //{
-            //    if (cc.Content == null)
-            //        yield return null;
-            //    if (cc.Content is T)
-            //        yield return cc.Content as T;
-            //    foreach (var child in FindVisualChildren<T>(cc.Content as DependencyObject))
-            //        yield return child;
-            //}
-            //else
-            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
-            {
-                var child = VisualTreeHelper.GetChild(depObj, i);
-                if (child is null)
-                    continue;
-
-                if (child is T t)
-                    yield return t;
-
-                foreach (var childOfChild in FindVisualChildren<T>(child))
-                    yield return childOfChild;
-            }
-    }
+    #endregion
 
 
     #region Grid Columns + Rows
     #region Grid Columns + Rows