150 lines
5.4 KiB
C#
150 lines
5.4 KiB
C#
using System.Reflection;
|
||
|
||
namespace RodionovLibrary.VisualComponents
|
||
{
|
||
public partial class ListBoxControl : UserControl
|
||
{
|
||
private string? _template;
|
||
|
||
private char? _fromChar;
|
||
|
||
private char? _toChar;
|
||
|
||
public int SelectedIndex
|
||
{
|
||
get
|
||
{
|
||
return listBox.SelectedIndex;
|
||
}
|
||
set
|
||
{
|
||
listBox.SelectedIndex = value;
|
||
}
|
||
}
|
||
|
||
public ListBoxControl()
|
||
{
|
||
InitializeComponent();
|
||
}
|
||
|
||
public void SetParams(string template, char fromChar, char toChar)
|
||
{
|
||
_template = template;
|
||
_fromChar = fromChar;
|
||
_toChar = toChar;
|
||
}
|
||
|
||
public T? GetObject<T>()
|
||
{
|
||
if (listBox.SelectedIndex == -1 || string.IsNullOrEmpty(_template) || !_fromChar.HasValue || !_toChar.HasValue)
|
||
throw new ArgumentException("Не хватает данных");
|
||
|
||
var type = typeof(T);
|
||
var fields = type.GetFields();
|
||
var properties = type.GetProperties();
|
||
var members = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>()).ToArray();
|
||
|
||
var curObject = Activator.CreateInstance(type) ?? throw new Exception("Не получилось создать объект заданного типа");
|
||
string text = listBox.SelectedItem?.ToString() ?? "";
|
||
|
||
var fixedParts = System.Text.RegularExpressions.Regex.Split(_template, $@"\{_fromChar.Value}.*?\{_toChar.Value}");
|
||
|
||
int firstFixedStart = text.IndexOf(fixedParts[0], 0);
|
||
if (firstFixedStart == -1)
|
||
throw new Exception("Не найден элемент шаблона");
|
||
if (firstFixedStart != 0)
|
||
{
|
||
string beginning = text[..firstFixedStart];
|
||
FillMember(_template.Substring(1, firstFixedStart - 2), curObject, beginning, members);
|
||
}
|
||
|
||
int start = 0;
|
||
|
||
for (int i = 0; i < fixedParts.Length - 1; i++)
|
||
{
|
||
start = text.IndexOf(fixedParts[i], start);
|
||
if (start == -1)
|
||
throw new Exception("Не найден элемент шаблона");
|
||
start += fixedParts[i].Length;
|
||
|
||
int nextFixedIndex = text.IndexOf(fixedParts[i + 1], start);
|
||
if (nextFixedIndex == -1)
|
||
throw new Exception("Не найден следующий элемент шаблона");
|
||
|
||
string valueBetween = text[start..nextFixedIndex];
|
||
|
||
string templatePart = _template.Substring(_template.IndexOf(fixedParts[i]) + fixedParts[i].Length);
|
||
int startCharIndex = templatePart.IndexOf(_fromChar.Value);
|
||
int endCharIndex = templatePart.IndexOf(_toChar.Value);
|
||
string memberName = templatePart.Substring(startCharIndex + 1, endCharIndex - startCharIndex - 1);
|
||
|
||
FillMember(memberName, curObject, valueBetween, members);
|
||
|
||
start = nextFixedIndex;
|
||
}
|
||
|
||
return (T?)curObject;
|
||
}
|
||
|
||
public void AddItems<T>(List<T> items)
|
||
where T : class
|
||
{
|
||
if (string.IsNullOrEmpty(_template) || !_fromChar.HasValue || !_toChar.HasValue)
|
||
throw new ArgumentException("Не хватает данных");
|
||
listBox.Items.Clear();
|
||
var type = typeof(T);
|
||
var fields = type.GetFields();
|
||
var properties = type.GetProperties();
|
||
var members = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>()).ToArray();
|
||
foreach (T item in items)
|
||
{
|
||
string result = _template;
|
||
foreach (var member in members)
|
||
{
|
||
string search = _fromChar.Value + member.Name + _toChar.Value;
|
||
object? value = null;
|
||
if (member is FieldInfo field)
|
||
{
|
||
value = field.GetValue(item);
|
||
}
|
||
if (member is PropertyInfo property)
|
||
{
|
||
if (property.CanRead)
|
||
{
|
||
value = property.GetValue(item);
|
||
}
|
||
}
|
||
result = result.Replace(search, value?.ToString() ?? "");
|
||
}
|
||
listBox.Items.Add(result);
|
||
}
|
||
}
|
||
|
||
private void FillMember(string memberName, object curObject, string value, MemberInfo[]? members)
|
||
{
|
||
var member = members?.FirstOrDefault(x => x.Name == memberName)
|
||
?? throw new Exception("Ошибка с поиском элемента");
|
||
object convertedValue = Convert.ChangeType(value, GetMemberType(member));
|
||
|
||
SetMemberValue(curObject, member, convertedValue);
|
||
}
|
||
|
||
private Type GetMemberType(MemberInfo member)
|
||
{
|
||
return member is PropertyInfo property ? property.PropertyType : ((FieldInfo)member).FieldType;
|
||
}
|
||
|
||
private void SetMemberValue(object obj, MemberInfo member, object value)
|
||
{
|
||
if (member is PropertyInfo property)
|
||
{
|
||
property.SetValue(obj, value);
|
||
}
|
||
else if (member is FieldInfo field)
|
||
{
|
||
field.SetValue(obj, value);
|
||
}
|
||
}
|
||
}
|
||
}
|