diff --git a/COP/RodionovLibrary/NonVisualComponents/WordTableComponent.cs b/COP/RodionovLibrary/NonVisualComponents/WordTableComponent.cs index e4f89ce..503c037 100644 --- a/COP/RodionovLibrary/NonVisualComponents/WordTableComponent.cs +++ b/COP/RodionovLibrary/NonVisualComponents/WordTableComponent.cs @@ -158,7 +158,7 @@ namespace RodionovLibrary.NonVisualComponents TableRow headerRow = new(); foreach (var column in columnParameters) { - TableCell cell = new(new Paragraph(new Run(new Text(column.Header == "MergeCell" ? "" : column.Header)))); + TableCell cell = new(new Paragraph(new Run(new Text(column.Header)))); TableCellProperties cellProps = new() { TableCellWidth = new TableCellWidth { Type = TableWidthUnitValues.Dxa, Width = (column.Width * 566.93).ToString("F0") }, diff --git a/COP/RodionovLibrary/VisualComponents/ComboBoxControl.cs b/COP/RodionovLibrary/VisualComponents/ComboBoxControl.cs index 46b0215..011912c 100644 --- a/COP/RodionovLibrary/VisualComponents/ComboBoxControl.cs +++ b/COP/RodionovLibrary/VisualComponents/ComboBoxControl.cs @@ -14,7 +14,7 @@ { get { - return comboBox.SelectedItem != null ? comboBox.SelectedItem.ToString()! : ""; + return comboBox.SelectedItem?.ToString() ?? ""; } set { diff --git a/COP/RodionovLibrary/VisualComponents/ListBoxControl.cs b/COP/RodionovLibrary/VisualComponents/ListBoxControl.cs index 22634b8..bb8dd77 100644 --- a/COP/RodionovLibrary/VisualComponents/ListBoxControl.cs +++ b/COP/RodionovLibrary/VisualComponents/ListBoxControl.cs @@ -1,4 +1,6 @@ -using System.Reflection; +using DocumentFormat.OpenXml.ExtendedProperties; +using DocumentFormat.OpenXml.Spreadsheet; +using System.Reflection; namespace RodionovLibrary.VisualComponents { @@ -40,33 +42,49 @@ namespace RodionovLibrary.VisualComponents throw new ArgumentException("Не хватает данных"); var type = typeof(T); + var fields = type.GetFields(); var properties = type.GetProperties(); - var curObject = Activator.CreateInstance(type); + var members = fields.Cast().Concat(properties.Cast()).ToArray(); - string[] wordsTemplate = _template.Split(' '); - string[] words = listBox.SelectedItem.ToString().Split(' '); + var curObject = Activator.CreateInstance(type) ?? throw new Exception("Не получилось создать объект заданного типа"); + string text = listBox.SelectedItem?.ToString() ?? ""; - for (int i = 0; i < wordsTemplate.Length; i++) + 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 word = wordsTemplate[i]; - if (word.Contains(_fromChar.Value) && word.Contains(_toChar.Value)) - { - int startCharIndex = word.IndexOf(_fromChar.Value); - int endCharIndex = word.LastIndexOf(_toChar.Value); - - string propertyName = word.Substring(startCharIndex + 1, endCharIndex - startCharIndex - 1); - var property = properties.FirstOrDefault(x => x.Name == propertyName); - if (property == null) - continue; - - int extraCharsBefore = startCharIndex; - int extraCharsAfter = word.Length - endCharIndex - 1; - - string propertyValue = words[i].Substring(extraCharsBefore, - words[i].Length - extraCharsBefore - extraCharsAfter); - property.SetValue(curObject, Convert.ChangeType(propertyValue, property.PropertyType)); - } + 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; } @@ -77,17 +95,57 @@ namespace RodionovLibrary.VisualComponents 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 property in properties) + foreach (var member in members) { - string search = _fromChar.Value + property.Name + _toChar.Value; - result = result.Replace(search, property.GetValue(item)?.ToString() ?? ""); + 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); + } + } } } diff --git a/COP/RodionovLibrary/VisualComponents/TextBoxControl.cs b/COP/RodionovLibrary/VisualComponents/TextBoxControl.cs index 8a2e9d2..2603e2a 100644 --- a/COP/RodionovLibrary/VisualComponents/TextBoxControl.cs +++ b/COP/RodionovLibrary/VisualComponents/TextBoxControl.cs @@ -47,7 +47,6 @@ namespace RodionovLibrary.VisualComponents private void TextBox_TextChanged(object sender, EventArgs e) { _valueChanged?.Invoke(sender, e); - Value = textBox.Text; } private void TextBox_MouseEnter(object sender, EventArgs e) diff --git a/COP/WinForms/FormTest.cs b/COP/WinForms/FormTest.cs index 3de8e94..44f31a0 100644 --- a/COP/WinForms/FormTest.cs +++ b/COP/WinForms/FormTest.cs @@ -99,12 +99,12 @@ namespace WinForms new() { Header = "", PropertyName = "", Width = 1.2 }, new() { Header = "", PropertyName = "", Width = 1.2 }, new() { Header = " ", PropertyName = "", Width = 1.6 }, - new() { Header = "MergeCell", PropertyName = "", Width = 1.6 }, - new() { Header = "MergeCell", PropertyName = "", Width = 1.6 }, + new() { Header = " ", PropertyName = "", Width = 1.6 }, + new() { Header = " ", PropertyName = "", Width = 1.6 }, new() { Header = "", PropertyName = "", Width = 1.2 }, new() { Header = "", PropertyName = "", Width = 1.6 }, new() { Header = "", PropertyName = "", Width = 2.5 }, - new() { Header = "MergeCell", PropertyName = "", Width = 2.5 }, + new() { Header = "", PropertyName = "", Width = 2.5 }, new() { Header = "", PropertyName = "", Width = 2 } };