using System.Reflection; namespace WinFormsLibrary { public partial class ListBoxValues : UserControl { private string _layout; private char? _endSymbol; private char? _startSymbol; public ListBoxValues() { InitializeComponent(); } public void SetLayout(string layout, char? startSymbol, char? endSymbol) { if (layout == null) { return; } _layout = layout; _endSymbol = endSymbol; _startSymbol = startSymbol; } public int SelectedIndex { get { if (listBoxObjects.SelectedIndex == -1) { return -1; } return listBoxObjects.SelectedIndex; } set { if (listBoxObjects.SelectedItems.Count != 0) { listBoxObjects.SelectedIndex = value; } } } public T GetObjectFromStr() where T : class, new() { if (listBoxObjects.SelectedIndex == -1 || string.IsNullOrEmpty(_layout) || !_startSymbol.HasValue || !_endSymbol.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 = new T(); string text = listBoxObjects.SelectedItem?.ToString() ?? ""; var words = System.Text.RegularExpressions.Regex.Split(_layout, $@"\{_startSymbol.Value}.*?\{_endSymbol.Value}"); int firstWordStart = text.IndexOf(words[0], 0); if (firstWordStart == -1) throw new Exception("Не найден элемент шаблона"); if (firstWordStart != 0) { string beginning = text[..firstWordStart]; FillMember(_layout.Substring(1, firstWordStart - 2), curObject, beginning, members); } int start = 0; for (int i = 0; i < words.Length - 1; i++) { start = text.IndexOf(words[i], start); if (start == -1) throw new Exception("Не найден элемент шаблона"); start += words[i].Length; int nextWordIndex = text.IndexOf(words[i + 1], start); if (nextWordIndex == -1) throw new Exception("Не найден следующий элемент шаблона"); string valueBetween = text[start..nextWordIndex]; string layoutPart = _layout.Substring(_layout.IndexOf(words[i]) + words[i].Length); int startCharIndex = layoutPart.IndexOf(_startSymbol.Value); int endCharIndex = layoutPart.IndexOf(_endSymbol.Value); string memberName = layoutPart.Substring(startCharIndex + 1, endCharIndex - startCharIndex - 1); FillMember(memberName, curObject, valueBetween, members); start = nextWordIndex; } return (T?)curObject; } public void AddItems(List items) where T : class { if (string.IsNullOrEmpty(_layout) || !_startSymbol.HasValue || !_endSymbol.HasValue) throw new ArgumentException("Не хватает данных"); listBoxObjects.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 = _layout; foreach (var member in members) { string search = _startSymbol.Value + member.Name +_endSymbol.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() ?? ""); } listBoxObjects.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); } } } }