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() { 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().Concat(properties.Cast()).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(List 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().Concat(properties.Cast()).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); } } } }