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? Clicked { get; set; } public object? DoClick(object? value) { var args = new DynamicGridMaskColumnButtonClickArgs(value); Clicked?.Invoke(this, args); return args.Value; } } public abstract class DynamicGridMaskColumn : DynamicGridEditorColumn where TEntity : BaseObject, new() where TEditor : class,new() { protected abstract Behavior? CreateBehaviour(); protected abstract IValueConverter? CreateConverter(); protected virtual Tuple 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