130 lines
3.4 KiB
C#
130 lines
3.4 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Interactivity;
|
|
|
|
namespace Inspectron.Settings.Avalonia.Configuration;
|
|
|
|
public partial class ItemEditorDialog : Window
|
|
{
|
|
private readonly Type _itemType;
|
|
private object? _workingValue;
|
|
private readonly DefaultControlFactory _controlFactory;
|
|
private readonly OptionsWindow _parentOptionsWindow;
|
|
|
|
public ItemEditorDialog(Type itemType, object? initialValue, DefaultControlFactory controlFactory, OptionsWindow parentOptionsWindow)
|
|
{
|
|
_itemType = itemType;
|
|
_workingValue = CloneObject(initialValue);
|
|
_controlFactory = controlFactory;
|
|
_parentOptionsWindow = parentOptionsWindow;
|
|
|
|
InitializeComponent();
|
|
Title = $"Edit {_itemType.Name}";
|
|
|
|
CreatePropertyControls();
|
|
|
|
BtnOK.Click += BtnOK_Click;
|
|
BtnCancel.Click += BtnCancel_Click;
|
|
}
|
|
|
|
private void CreatePropertyControls()
|
|
{
|
|
if (_itemType.IsValueType || _itemType == typeof(string))
|
|
{
|
|
CreateSimpleValueControl();
|
|
}
|
|
else
|
|
{
|
|
CreateComplexObjectControls();
|
|
}
|
|
}
|
|
|
|
private void CreateSimpleValueControl()
|
|
{
|
|
var dummyProperty = new SimplePropertyInfo(_itemType, "Value");
|
|
var control = _controlFactory.CreateControl("Value", "Value", dummyProperty, _workingValue!,
|
|
newValue => _workingValue = newValue, _parentOptionsWindow);
|
|
|
|
PropertyPanel.Children.Add(control);
|
|
}
|
|
|
|
private void CreateComplexObjectControls()
|
|
{
|
|
var properties = _itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
|
.Where(p => p.CanRead && p.CanWrite)
|
|
.ToArray();
|
|
|
|
foreach (var property in properties)
|
|
{
|
|
var currentValue = property.GetValue(_workingValue);
|
|
var control = _controlFactory.CreateControl(property.Name, property.Name, property, currentValue!,
|
|
newValue => property.SetValue(_workingValue, newValue), _parentOptionsWindow);
|
|
|
|
PropertyPanel.Children.Add(control);
|
|
}
|
|
}
|
|
|
|
private void BtnOK_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
Close(_workingValue);
|
|
}
|
|
|
|
private void BtnCancel_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
Close(null);
|
|
}
|
|
|
|
private object? CloneObject(object? obj)
|
|
{
|
|
if (obj == null) return GetDefaultValue(_itemType);
|
|
|
|
var type = obj.GetType();
|
|
if (type.IsValueType || type == typeof(string))
|
|
{
|
|
return obj;
|
|
}
|
|
|
|
try
|
|
{
|
|
var clone = Activator.CreateInstance(type);
|
|
foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
|
{
|
|
if (prop.CanRead && prop.CanWrite)
|
|
{
|
|
prop.SetValue(clone, prop.GetValue(obj));
|
|
}
|
|
}
|
|
return clone;
|
|
}
|
|
catch
|
|
{
|
|
return GetDefaultValue(type);
|
|
}
|
|
}
|
|
|
|
private object? GetDefaultValue(Type type)
|
|
{
|
|
if (type.IsValueType)
|
|
{
|
|
return Activator.CreateInstance(type);
|
|
}
|
|
else if (type == typeof(string))
|
|
{
|
|
return "";
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
return Activator.CreateInstance(type);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|