PIbd-31_Rodionov.I.A._COP_28/COP/RodionovLibrary/VisualComponents/ListBoxControl.cs

152 lines
5.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DocumentFormat.OpenXml.ExtendedProperties;
using DocumentFormat.OpenXml.Spreadsheet;
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);
}
}
}
}