using InABox.Core;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
namespace InABox.DynamicGrid
{
public delegate void FieldChangedEvent();
public interface IDynamicFormFieldControl
{
public event FieldChangedEvent? FieldChangedEvent;
void Deserialize(DFLoadStorageEntry storage);
void Serialize(DFSaveStorageEntry storage);
public object? GetValue();
///
/// Sets the value in this control.
///
/// The value to set. This will be the return value from a call to .
public void SetValue(object? value);
public object? GetEntityValue();
public void SetEntityValue(object? value);
///
/// Gets additional data for this field by the specific field name of .
///
/// A name which specifies what data is requested.
/// The additional data.
public object? GetData(string field);
///
/// Gets additional data for this field that should be saved into the form data.
///
/// The additional data.
public Dictionary? GetAdditionalValues();
///
/// Check that the data is valid - if it is not, output a message for the user.
/// This function gets called when the user completes a form, or edits an already completed form.
///
/// The message to the user.
/// if the data is valid.
public bool Validate([NotNullWhen(false)] out string? message);
}
public abstract class DynamicFormFieldControl : DynamicFormControl, IDynamicFormFieldControl
where TField : DFLayoutField
where TProperties : DFLayoutFieldProperties, new()
{
public event FieldChangedEvent? FieldChangedEvent;
public TField Field { get => Control; set => Control = value; }
public void Serialize(DFSaveStorageEntry storage)
{
Field.Properties.SerializeValue(storage, GetSerializedValue());
}
public void Deserialize(DFLoadStorageEntry storage)
{
SetSerializedValue(Field.Properties.DeserializeValue(storage));
}
protected void ChangeField() => FieldChangedEvent?.Invoke();
///
/// Checks whether the user has supplied a field - for use with .
///
/// if the user has not supplied a value.
protected abstract bool IsEmpty();
public virtual bool Validate([NotNullWhen(false)] out string? message)
{
if(Field.Properties.Required && IsEmpty())
{
message = $"Field [{Field.Name}] is required!";
return false;
}
message = null;
return true;
}
protected override void AfterSetControl(TField control)
{
base.AfterSetControl(control);
if (!string.IsNullOrWhiteSpace(control.Properties.Expression) || control.Properties.ReadOnlyProperty)
{
IsEnabled = false;
}
}
public abstract TSerialized GetSerializedValue();
public abstract void SetSerializedValue(TSerialized value);
public abstract TValue GetValue();
public abstract void SetValue(TValue? value);
public virtual object? GetEntityValue() => GetValue();
public virtual void SetEntityValue(object? value) => SetValue(CoreUtils.ChangeType(value));
public virtual object? GetData(string dataField)
{
return null;
}
public virtual Dictionary? GetAdditionalValues()
{
return null;
}
object? IDynamicFormFieldControl.GetValue() => GetValue();
void IDynamicFormFieldControl.SetValue(object? value) => SetValue(value != null ? (TValue)value : default);
}
}