Files
2025-07-19 15:57:59 +02:00

163 lines
4.8 KiB
C#

using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace Inspectron.Settings.Windows.Configuration;
public partial class ItemEditorDialog : Form
{
private readonly Type _itemType;
private object _workingValue;
private readonly DefaultControlFactory _controlFactory;
private readonly OptionsWindow _parentOptionsWindow;
private FlowLayoutPanel _propertyPanel;
private Button _okButton;
private Button _cancelButton;
public ItemEditorDialog(Type itemType, object initialValue, DefaultControlFactory controlFactory, OptionsWindow parentOptionsWindow)
{
_itemType = itemType;
_workingValue = CloneObject(initialValue);
_controlFactory = controlFactory;
_parentOptionsWindow = parentOptionsWindow;
InitializeComponent();
CreatePropertyControls();
}
private void InitializeComponent()
{
this.Text = $"Edit {_itemType.Name}";
this.Size = new System.Drawing.Size(650, 420);
this.StartPosition = FormStartPosition.CenterParent;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
_propertyPanel = new FlowLayoutPanel
{
Location = new System.Drawing.Point(12, 12),
Size = new System.Drawing.Size(620, 320),
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom,
FlowDirection = FlowDirection.TopDown,
AutoScroll = true
};
_okButton = new Button
{
Text = "OK",
Location = new System.Drawing.Point(470, 340),
Size = new System.Drawing.Size(75, 23),
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
DialogResult = DialogResult.OK
};
_cancelButton = new Button
{
Text = "Cancel",
Location = new System.Drawing.Point(550, 340),
Size = new System.Drawing.Size(75, 23),
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
DialogResult = DialogResult.Cancel
};
this.Controls.AddRange(new Control[] { _propertyPanel, _okButton, _cancelButton });
}
private void CreatePropertyControls()
{
if (_itemType.IsValueType || _itemType == typeof(string))
{
// For simple types, create a single control
CreateSimpleValueControl();
}
else
{
// For complex types, create controls for each property
CreateComplexObjectControls();
}
}
private void CreateSimpleValueControl()
{
var dummyProperty = new SimplePropertyInfo(_itemType, "Value");
var control = _controlFactory.CreateControl("Value", "Value", dummyProperty, _workingValue,
newValue => _workingValue = newValue, _parentOptionsWindow);
_propertyPanel.Controls.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.Controls.Add(control);
}
}
public object GetEditedValue()
{
return _workingValue;
}
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;
}
}
}
}