using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; using InABox.Clients; using InABox.Core; namespace InABox.DynamicGrid; public class CodePopupEditorControl : DynamicEditorControl { static CodePopupEditorControl() { //DynamicEditorControlFactory.Register(); } private Type _type; private Guid _value = Guid.Empty; private TextBox Description; private TextBox Editor; private string origvalue = ""; public string CodeColumn { get; set; } protected override FrameworkElement CreateEditor() { var Grid = new Grid { VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch }; Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(131, GridUnitType.Pixel) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(19, GridUnitType.Pixel) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); Editor = new TextBox { CharacterCasing = CharacterCasing.Upper, VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch }; Editor.BorderThickness = new Thickness(1,1,0,1); Editor.BorderBrush = new SolidColorBrush(Colors.Silver); Editor.SetValue(Grid.ColumnProperty, 0); Editor.SetValue(Grid.RowProperty, 0); Editor.PreviewKeyDown += Editor_PreviewKeyDown; Editor.GotFocus += Editor_GotFocus; Editor.AcceptsTab = true; Editor.LostFocus += Editor_LostFocus; Grid.Children.Add(Editor); var Select = new Button { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Content = "..", Focusable = false }; Select.BorderThickness = new Thickness(1); Select.BorderBrush = new SolidColorBrush(Colors.DimGray); Select.SetValue(Grid.ColumnProperty, 1); Select.SetValue(Grid.RowProperty, 0); Select.Click += Select_Click; Grid.Children.Add(Select); Description = new TextBox { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5, 0, 0, 0), IsReadOnly = true, Focusable = false, Background = new SolidColorBrush(Colors.WhiteSmoke), BorderBrush = new SolidColorBrush(Colors.Silver) }; Description.SetValue(Grid.ColumnProperty, 2); Description.SetValue(Grid.RowProperty, 0); Grid.Children.Add(Description); return Grid; } private void Editor_GotFocus(object sender, RoutedEventArgs e) { origvalue = Editor.Text; } private void Editor_LostFocus(object sender, RoutedEventArgs e) { if (Editor.Text.Equals(origvalue)) return; var id = _value; LookupValue(CodeColumn, Editor.Text); if (id == Guid.Empty) CheckChanged(); } private void Editor_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key.Equals(Key.Enter) || e.Key.Equals(Key.Tab)) { if (string.IsNullOrEmpty(Editor.Text)) { if (!Editor.Text.Equals(origvalue)) { LookupValue("ID", Guid.Empty); CheckChanged(); } Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); } else { if (!Editor.Text.Equals(origvalue)) { var code = Editor.Text; LookupValue(CodeColumn, code); if (_value != Guid.Empty) { CheckChanged(); Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); } else { if (DoSearch(code)) Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); } } else { Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); } } e.Handled = true; } } private void Editor_PreviewKeyUp(object sender, KeyEventArgs e) { } private void Editor_KeyUp(object sender, KeyEventArgs e) { } private void Select_Click(object sender, RoutedEventArgs e) { DoSearch(Editor.Text); } private bool DoSearch(string code) { var result = false; if (_type != null) { var columns = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName); var list = new PopupList(_type, _value, columns.ColumnNames().Concat(CoreUtils.One(CodeColumn)).ToArray(), new Dictionary { { CodeColumn, code } }); list.OnDefineFilter += t => LookupFactory.DefineLookupFilter(Host.GetEditorType(), t, ColumnName, Host.GetItems()); list.OnCustomiseGrid += grid => { if (EditorDefinition.CanAdd) { grid.OnDoubleClick += (o, args) => args.Handled = true; grid.OnReconfigure += options => { options.AddRows = Security.CanEdit(_type); options.EditRows = Security.CanEdit(_type); options.EditRows = Security.CanDelete(_type); options.ReadOnly = false; }; grid.OnCreateItem += (_, item) => { LookupFactory.OnCreateItem(Host.GetEditorType(), ColumnName, Host.GetItems(), item); EditorDefinition.OnCreateItem?.Invoke(item); }; grid.Reconfigure(); } }; if (list.ShowDialog() == true) { result = true; _value = list.ID; foreach (var col in columns) OtherValues[col.Property] = list.OtherValues[col.Property]; CheckChanged(); Editor.Text = string.Format("{0}", list.OtherValues[CodeColumn]); var display = new Dictionary(); foreach (var key in list.OtherValues.Keys.Where(x => !string.Equals(x, CodeColumn))) display[key] = list.OtherValues[key]; Description.Text = LookupFactory.FormatLookup(_type, display, new[] { CodeColumn }); } } return result; } public override int DesiredHeight() { return 25; } public override int DesiredWidth() { return int.MaxValue; } protected override Guid RetrieveValue() { return _value; } protected override void UpdateValue(Guid value) { var oldvalue = _value; _value = value; if (oldvalue != value) { if (Equals(value, Guid.Empty)) SetEmptyValue(); else LookupValue("ID", value); CheckChanged(); } } private void SetEmptyValue() { Editor.Text = ""; Description.Text = ""; } private void LookupValue(string column, object value) { var client = ClientFactory.CreateClient(_type); var columns = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName); columns.Add(CodeColumn); var sort = LookupFactory.DefineSort(_type); var filter = Filter.Create(_type, column).IsEqualTo(value); var lookup = client.Query(filter, columns, sort); var display = new Dictionary(); var code = ""; var id = Guid.Empty; var displaycols = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName).ColumnNames(); var row = lookup.Rows.FirstOrDefault(); row ??= lookup.NewRow(true); code = row[CodeColumn]?.ToString(); id = row.Get("ID"); foreach (var col in displaycols.Where(x => !x.Equals("ID") && !x.Equals(CodeColumn))) display[col] = row[col]; foreach(var col in columns) { OtherValues[col.Property] = row[col.Property]; } _value = id; Editor.Text = code; Description.Text = LookupFactory.FormatLookup(_type, display, new[] { CodeColumn }); } private string GetCodeColumn(Type type) { var prop = DatabaseSchema.Properties(type) .Where(x => x.Editor is UniqueCodeEditor && !x.HasParentEntityLink()) .FirstOrDefault() ?? throw new Exception($"No code property for {type.EntityName()}"); return prop.Name; } public override void Configure() { _type = EditorDefinition.Type; CodeColumn = !string.IsNullOrEmpty(EditorDefinition.CodeColumn) ? EditorDefinition.CodeColumn : GetCodeColumn(_type); } public override void SetFocus() { Editor.Focus(); } public override void SetColor(Color color) { Editor.Background = IsEnabled ? new SolidColorBrush(color) : new SolidColorBrush(Colors.WhiteSmoke); } }