diff --git a/WinFormsLibrary1/WinFormsLibrary1/ListBox.cs b/WinFormsLibrary1/WinFormsLibrary1/ListBox.cs index fb0d8d8..dc905e4 100644 --- a/WinFormsLibrary1/WinFormsLibrary1/ListBox.cs +++ b/WinFormsLibrary1/WinFormsLibrary1/ListBox.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; @@ -10,9 +11,9 @@ namespace WinFormsLibrary1 { private string? _template; - private string _startSymbol; + private char? _startSymbol; - private string _endSymbol; + private char? _endSymbol; public int SelectedIndex { get @@ -24,11 +25,13 @@ namespace WinFormsLibrary1 listBox.SelectedIndex = value; } } + public ListBoxUserControl() { InitializeComponent(); } - public void SetParams(string template, string fromChar, string toChar) + + public void SetParams(string template, char? fromChar, char? toChar) { _template = template; _startSymbol = fromChar; @@ -37,62 +40,81 @@ namespace WinFormsLibrary1 public T? GetObject() where T : class, new() { - if (listBox.SelectedIndex == -1) + if (listBox.SelectedIndex == -1 || string.IsNullOrEmpty(_template) || !_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 = listBox.SelectedItem?.ToString() ?? ""; + + var words = Regex.Split(_template, $@"\{_startSymbol.Value}.*?\{_endSymbol.Value}"); + + int firstWordStart = text.IndexOf(words[0], 0); + if (firstWordStart == -1) + throw new Exception("Не найден элемент шаблона"); + if (firstWordStart != 0) { - return null; + string beginning = text[..firstWordStart]; + FillMember(_template.Substring(1, firstWordStart - 2), curObject, beginning, members); } - string selectedString = listBox.SelectedItem.ToString()!; - T obj = new T(); + int start = 0; - string pattern = $@"{Regex.Escape(_startSymbol)}(.*?){Regex.Escape(_endSymbol)}"; - MatchCollection matches = Regex.Matches(_template, pattern); - - string[] words = selectedString.Split(' '); - - int wordIndex = 0; - - foreach (Match match in matches) + for (int i = 0; i < words.Length - 1; i++) { - string propertyName = match.Groups[1].Value; - var property = obj.GetType().GetProperty(propertyName); - if (property != null && property.CanWrite) - { - if (wordIndex < words.Length) - { - string propertyValue = words[wordIndex]; - property.SetValue(obj, Convert.ChangeType(propertyValue, property.PropertyType)); - wordIndex++; - } - } + 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 = _template.Substring(_template.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 obj; + return (T?)curObject; + } - public void AddObject(T obj) + private void SetMemberValue(object obj, MemberInfo member, object value) { - if (obj == null) + if (member is PropertyInfo property) { - throw new ArgumentNullException("Добавляемый объект не существует!"); + property.SetValue(obj, value); } - if (string.IsNullOrEmpty(_template) || string.IsNullOrEmpty(_startSymbol) || string.IsNullOrEmpty(_endSymbol)) + else if (member is FieldInfo field) { - throw new Exception("Заполните макетную строку!"); - } - if (!_template.Contains(_startSymbol) || !_template.Contains(_endSymbol)) - { - throw new Exception("Макетная строка не содержит нужные элементы!"); + field.SetValue(obj, value); } + } - string processedString = _template; - foreach (var property in obj.GetType().GetProperties()) - { - string placeholder = $"{_startSymbol}{property.Name}{_endSymbol}"; - processedString = processedString.Replace(placeholder, $"{_startSymbol}{property.GetValue(obj)}{_endSymbol}"); - } + 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)); - listBox.Items.Add(processedString); + SetMemberValue(curObject, member, convertedValue); + } + + private Type GetMemberType(MemberInfo member) + { + return member is PropertyInfo property ? property.PropertyType : ((FieldInfo)member).FieldType; } } } \ No newline at end of file