| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 | using System;using System.Collections.Generic;using System.Globalization;using System.Linq;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Media;using System.Windows.Media.Imaging;using InABox.Core;using InABox.WPF;using Microsoft.Xaml.Behaviors;using Syncfusion.UI.Xaml.Grid;using Syncfusion.UI.Xaml.TreeGrid;namespace InABox.DynamicGrid;public class DynamicGridMaskColumnButtonClickArgs{    public object? Value { get; set; }    public DynamicGridMaskColumnButtonClickArgs(object? value)    {        Value = value;    }}public enum DynamicGridMaskColumnButtonPosition{    Left,    Right}public class DynamicGridMaskColumnButton{    public BitmapImage? Image { get; set; }        public Visibility Visibility { get; set; }    public DynamicGridMaskColumnButtonPosition Position { get; set; } = DynamicGridMaskColumnButtonPosition.Right;        public Action<DynamicGridMaskColumnButton,DynamicGridMaskColumnButtonClickArgs>? Clicked { get; set; }    public object? DoClick(object? value)    {        var args = new DynamicGridMaskColumnButtonClickArgs(value);        Clicked?.Invoke(this, args);        return args.Value;    }}public abstract class DynamicGridMaskColumn<TEditor> : DynamicGridEditorColumn< TEditor, GridTemplateColumn, TreeGridTemplateColumn>    where TEditor : class,new() {    protected abstract Behavior? CreateBehaviour();    protected abstract IValueConverter? CreateConverter();    protected virtual Tuple<DataTemplate, DataTemplate> CreateTemplates(GridColumnBase column, TEditor editor, string mapping)    {        var converter = CreateConverter();        var cellTemplate = TemplateGenerator.CreateDataTemplate        (            () =>            {                var result = new Label                {                    HorizontalContentAlignment = column.TextAlignment == TextAlignment.Left                        ? HorizontalAlignment.Left                        : column.TextAlignment == TextAlignment.Center                            ? HorizontalAlignment.Center                            : HorizontalAlignment.Right,                    VerticalContentAlignment = VerticalAlignment.Center                };                var binding = new Binding()                {                    Path = new PropertyPath(mapping),                    Converter = converter                };                result.SetBinding(Label.ContentProperty, binding);                return result;            }        );        var editTemplate = TemplateGenerator.CreateDataTemplate        (            () =>            {                var border = new Border()                {                    BorderBrush = new SolidColorBrush(Colors.Gray),                    BorderThickness = new Thickness(0.75),                    Padding = new Thickness(0),                    Margin = new Thickness(0)                };                                    var dock = new DockPanel();                dock.SourceUpdated += OnSourceUpdated;                dock.TargetUpdated += OnTargetUpdated;                border.Child = dock;                                var textbox = new TextBox                {                    CharacterCasing = CharacterCasing.Upper,                    TextAlignment = column.TextAlignment,                    BorderThickness = new Thickness(0),                    //Padding = new Thickness(2, 0, 0, 0),                    VerticalContentAlignment = VerticalAlignment.Center,                    Background = new SolidColorBrush(Colors.White)                };                                textbox.SetBinding(TextBox.TextProperty, new Binding()                {                    Path = new PropertyPath(mapping),                    Converter = converter,                    NotifyOnSourceUpdated = true,                    NotifyOnTargetUpdated = true,                });                                var behaviour = CreateBehaviour();                if (behaviour != null)                    Interaction.GetBehaviors(textbox).Add(behaviour);                                textbox.SetValue(FocusManagerHelper.FocusedElementProperty, true);                textbox.SetValue(DockPanel.DockProperty,Dock.Left);                                var defs = CreateButtons();                if (defs?.Any() == true)                {                    foreach (var def in defs)                    {                        Button button = new Button()                        {                            Tag = def,                            Content = new Image() { Source = def.Image },                            Padding = new Thickness(2),                            Width = 25,                            BorderThickness = new Thickness(0),                            Background = new SolidColorBrush(Colors.White),                            Visibility = def.Visibility,                        };                        button.Click += (sender, args) =>                        {                            var cvt = CreateConverter();                            var val = cvt != null                                ? cvt.ConvertBack(textbox.Text, typeof(object), null, CultureInfo.CurrentCulture)                                : textbox.Text;                            val = def.DoClick(val);                            textbox.Text = cvt != null                                ? cvt.Convert(val, typeof(String), null, CultureInfo.CurrentCulture) as String ?? ""                                : val?.ToString() ?? "";                            textbox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();                            button.Content = new Image() { Source = def.Image };                            button.Visibility = def.Visibility;                        };                        button.SetValue(DockPanel.DockProperty,def.Position == DynamicGridMaskColumnButtonPosition.Left ? Dock.Left : Dock.Right);                        dock.Children.Add(button);                    }                }                                dock.Children.Add(textbox);                                return border;            }                    );        return new(cellTemplate, editTemplate);    }        protected override void Configure(GridTemplateColumn column, TEditor editor)    {        var (cellTemplate, editTemplate) = CreateTemplates(column, editor, MappingName);        column.CellTemplate = cellTemplate;        column.EditTemplate = editTemplate;                column.SetCellBoundValue = false;    }    protected override void Configure(TreeGridTemplateColumn column, TEditor editor)    {        var (cellTemplate, editTemplate) = CreateTemplates(column, editor, TreeMappingName);        column.CellTemplate = cellTemplate;        column.EditTemplate = editTemplate;                column.SetCellBoundValue = false;    }    protected virtual DynamicGridMaskColumnButton[]? CreateButtons()    {        return null;    }        private void OnTargetUpdated(object? sender, DataTransferEventArgs e)    {        if (sender is DockPanel dock && e.Source is TextBox textbox && e.Property == TextBox.TextProperty)        {            var buttons = dock?.Children.OfType<Button>().ToArray();            var defs = buttons?.Select(x => x.Tag).OfType<DynamicGridMaskColumnButton>()?.ToArray();            if (defs?.Any() == true)            {                var cvt = CreateConverter();                var val = cvt != null                    ? cvt.ConvertBack(textbox.Text, typeof(object), null, CultureInfo.CurrentCulture)                    : textbox.Text;                UpdateButtons(val, defs);                if (buttons != null)                    foreach (var button in buttons)                    {                        var def = button.Tag as DynamicGridMaskColumnButton;                        button.Content = new Image() { Source = def?.Image };                        button.Visibility = def?.Visibility ?? Visibility.Collapsed;                    }            }        }    }        protected virtual void UpdateButtons(object? value, DynamicGridMaskColumnButton[]? buttons)    {            }    private void OnSourceUpdated(object? sender, DataTransferEventArgs e)    {        if (sender is DockPanel dock && e.Source is TextBox textbox && e.Property == TextBox.TextProperty)        {            var buttons = dock?.Children.OfType<Button>().ToArray();            SourceUpdated(textbox.Text, buttons ?? new Button[] { });        }    }    protected virtual void SourceUpdated(string text, Button[] buttons)    {            }    protected DynamicGridMaskColumn(DynamicGridColumn definition) : base(definition)    {    }}
 |