DynamicFormFieldControl.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using InABox.Core;
  2. using System.Collections.Generic;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
  10. namespace InABox.DynamicGrid
  11. {
  12. public delegate void FieldChangedEvent();
  13. public interface IDynamicFormFieldControl
  14. {
  15. public event FieldChangedEvent? FieldChangedEvent;
  16. void Deserialize(DFLoadStorageEntry storage);
  17. void Serialize(DFSaveStorageEntry storage);
  18. public object? GetValue();
  19. /// <summary>
  20. /// Sets the value in this control.
  21. /// </summary>
  22. /// <param name="value">The value to set. This will be the return value from a call to <see cref="DFLayoutFieldProperties.ParseValue(object)"/>.</param>
  23. public void SetValue(object? value);
  24. public object? GetEntityValue();
  25. public void SetEntityValue(object? value);
  26. /// <summary>
  27. /// Gets additional data for this field by the specific field name of <paramref name="field"/>.
  28. /// </summary>
  29. /// <param name="field">A name which specifies what data is requested.</param>
  30. /// <returns>The additional data.</returns>
  31. public object? GetData(string field);
  32. /// <summary>
  33. /// Gets additional data for this field that should be saved into the form data.
  34. /// </summary>
  35. /// <returns>The additional data.</returns>
  36. public Dictionary<string, object?>? GetAdditionalValues();
  37. /// <summary>
  38. /// Check that the data is valid - if it is not, output a message for the user.
  39. /// This function gets called when the user completes a form, or edits an already completed form.
  40. /// </summary>
  41. /// <param name="message">The message to the user.</param>
  42. /// <returns><see langword="true"/> if the data is valid.</returns>
  43. public bool Validate([NotNullWhen(false)] out string? message);
  44. }
  45. public abstract class DynamicFormFieldControl<TField, TProperties, TValue, TSerialized> : DynamicFormControl<TField>, IDynamicFormFieldControl
  46. where TField : DFLayoutField<TProperties>
  47. where TProperties : DFLayoutFieldProperties<TValue, TSerialized>, new()
  48. {
  49. public event FieldChangedEvent? FieldChangedEvent;
  50. public TField Field { get => Control; set => Control = value; }
  51. public void Serialize(DFSaveStorageEntry storage)
  52. {
  53. Field.Properties.SerializeValue(storage, GetSerializedValue());
  54. }
  55. public void Deserialize(DFLoadStorageEntry storage)
  56. {
  57. SetSerializedValue(Field.Properties.DeserializeValue(storage));
  58. }
  59. protected void ChangeField() => FieldChangedEvent?.Invoke();
  60. /// <summary>
  61. /// Checks whether the user has supplied a field - for use with <see cref="Validate(out string?)"/>.
  62. /// </summary>
  63. /// <returns><see langword="true"/> if the user has not supplied a value.</returns>
  64. protected abstract bool IsEmpty();
  65. public virtual bool Validate([NotNullWhen(false)] out string? message)
  66. {
  67. if(Field.Properties.Required && IsEmpty())
  68. {
  69. message = $"Field [{Field.Name}] is required!";
  70. return false;
  71. }
  72. message = null;
  73. return true;
  74. }
  75. protected override void AfterSetControl(TField control)
  76. {
  77. base.AfterSetControl(control);
  78. if (!string.IsNullOrWhiteSpace(control.Properties.Expression) || control.Properties.ReadOnlyProperty)
  79. {
  80. IsEnabled = false;
  81. }
  82. }
  83. public abstract TSerialized GetSerializedValue();
  84. public abstract void SetSerializedValue(TSerialized value);
  85. public abstract TValue GetValue();
  86. public abstract void SetValue(TValue? value);
  87. public virtual object? GetEntityValue() => GetValue();
  88. public virtual void SetEntityValue(object? value) => SetValue(CoreUtils.ChangeType<TValue>(value));
  89. public virtual object? GetData(string dataField)
  90. {
  91. return null;
  92. }
  93. public virtual Dictionary<string, object?>? GetAdditionalValues()
  94. {
  95. return null;
  96. }
  97. object? IDynamicFormFieldControl.GetValue() => GetValue();
  98. void IDynamicFormFieldControl.SetValue(object? value) => SetValue(value != null ? (TValue)value : default);
  99. }
  100. }