CustomListBox Fix

This commit is contained in:
parent df692293b8
commit 58e1420ff8
3 changed files with 86 additions and 62 deletions

View File

@ -1,10 +1,13 @@
using System; using Components.VisualComponents.HelperModels;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -16,19 +19,9 @@ namespace Components.VisualComponents
public partial class CustomListBox : UserControl public partial class CustomListBox : UserControl
{ {
/// <summary> /// <summary>
/// Макетная строка /// Конфигурация
/// </summary> /// </summary>
private string _layoutString; private CustomListBoxConfig _config;
/// <summary>
/// Символ начала имени свойства
/// </summary>
private string _startSymbol;
/// <summary>
/// Символ конца имени свойства
/// </summary>
private string _endSymbol;
/// <summary> /// <summary>
/// Индекс выбранной строки /// Индекс выбранной строки
@ -37,11 +30,6 @@ namespace Components.VisualComponents
{ {
get get
{ {
if (listBox.SelectedIndex == -1)
{
return -1;
}
return listBox.SelectedIndex; return listBox.SelectedIndex;
} }
@ -63,25 +51,26 @@ namespace Components.VisualComponents
} }
/// <summary> /// <summary>
/// Установить макетную строку /// Задать конфигурацию
/// </summary> /// </summary>
/// <param name="layoutString"></param> /// <param name="config"></param>
/// <param name="startSymbol"></param> /// <exception cref="Exception"></exception>
/// <param name="endSymbol"></param> public void SetConfig(CustomListBoxConfig config)
public void SetLayoutInfo(string layoutString, string startSymbol, string endSymbol)
{ {
if (string.IsNullOrEmpty(layoutString) || string.IsNullOrEmpty(startSymbol) || string.IsNullOrEmpty(endSymbol)) if (_config != null)
{
throw new Exception("Конфигурация уже задана!");
}
if (string.IsNullOrEmpty(config.LayoutString) || string.IsNullOrEmpty(config.StartSymbol) || string.IsNullOrEmpty(config.EndSymbol))
{ {
throw new Exception("Заполните макетную строку!"); throw new Exception("Заполните макетную строку!");
} }
if (!layoutString.Contains(startSymbol) || !layoutString.Contains(endSymbol)) if (!config.LayoutString.Contains(config.StartSymbol) || !config.LayoutString.Contains(config.EndSymbol))
{ {
throw new Exception("Макетная строка не содержит нужные элементы!"); throw new Exception("Макетная строка не содержит нужные элементы!");
} }
_layoutString = layoutString; _config = config;
_startSymbol = startSymbol;
_endSymbol = endSymbol;
} }
/// <summary> /// <summary>
@ -91,37 +80,28 @@ namespace Components.VisualComponents
/// <returns></returns> /// <returns></returns>
public T? GetObject<T>() where T : class, new() public T? GetObject<T>() where T : class, new()
{ {
if (listBox.SelectedIndex == -1) if (listBox.SelectedIndex == -1 || _config == null)
{ {
return null; return null;
} }
string selectedString = listBox.SelectedItem.ToString()!; string selectedString = listBox.SelectedItem.ToString()!;
StringBuilder sb = new StringBuilder(selectedString); string layoutString = _config.LayoutString;
T obj = new T(); T obj = new T();
foreach (var property in obj.GetType().GetProperties()) string[] layoutParts = Regex.Split(layoutString, _config.Pattern);
for (int i = 0; i < layoutParts.Length - 1; i++)
{ {
if (!property.CanWrite) int startPosition;
{ string matchedText = GetSubstring(layoutParts[i], layoutParts[i + 1], selectedString, out startPosition);
continue; selectedString = selectedString.Remove(0, startPosition + matchedText.Length);
}
int firstBorder = sb.ToString().IndexOf(_startSymbol); string patternSegment = GetSubstring(layoutParts[i], layoutParts[i + 1], layoutString, out startPosition);
if (firstBorder == -1) layoutString = layoutString.Remove(0, startPosition + patternSegment.Length);
{
break;
}
int secondBorder = sb.ToString().IndexOf(_endSymbol, firstBorder + 1); patternSegment = patternSegment.Substring(1, patternSegment.Length - 2);
if (secondBorder == -1) PropertyInfo property = obj.GetType().GetProperty(patternSegment);
{ property?.SetValue(obj, Convert.ChangeType(matchedText, property?.PropertyType));
break;
}
string propertyValue = sb.ToString(firstBorder + 1, secondBorder - firstBorder - 1);
sb.Remove(0, secondBorder + 1);
property.SetValue(obj, Convert.ChangeType(propertyValue, property.PropertyType));
} }
return obj; return obj;
@ -140,23 +120,28 @@ namespace Components.VisualComponents
{ {
throw new ArgumentNullException("Добавляемый объект не существует!"); throw new ArgumentNullException("Добавляемый объект не существует!");
} }
if (string.IsNullOrEmpty(_layoutString) || string.IsNullOrEmpty(_startSymbol) || string.IsNullOrEmpty(_endSymbol)) if (_config == null)
{ {
throw new Exception("Заполните макетную строку!"); throw new Exception("Конфигурация не задана!");
}
if (!_layoutString.Contains(_startSymbol) || !_layoutString.Contains(_endSymbol))
{
throw new Exception("Макетная строка не содержит нужные элементы!");
} }
string processedString = _layoutString; string processedString = _config.LayoutString;
foreach (var property in obj.GetType().GetProperties()) MatchCollection matchCollection = Regex.Matches(_config.LayoutString, _config.Pattern);
foreach (Match item in matchCollection)
{ {
string placeholder = $"{_startSymbol}{property.Name}{_endSymbol}"; string propertyName = item.Value.Remove(item.Value.Length - 1, 1).Remove(0, 1);
processedString = processedString.Replace(placeholder, $"{_startSymbol}{property.GetValue(obj)}{_endSymbol}"); processedString = processedString.Replace($"{_config.StartSymbol}{propertyName}{_config.EndSymbol}", obj.GetType().GetProperty(propertyName)?.GetValue(obj, null)?.ToString());
} }
listBox.Items.Add(processedString); listBox.Items.Add(processedString);
} }
private string GetSubstring(string startDelimiter, string endDelimiter, string baseString, out int startPosition)
{
startPosition = startDelimiter.Length;
int endPosition = baseString.IndexOf(endDelimiter) - 1;
endPosition = (endPosition >= startPosition) ? endPosition : (baseString.Length - 1);
return baseString.Substring(startPosition, endPosition - startPosition + 1);
}
} }
} }

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.VisualComponents.HelperModels
{
/// <summary>
/// Вспомогательный класс конфигурации для CustomListBox
/// </summary>
public class CustomListBoxConfig
{
/// <summary>
/// Макетная строка
/// </summary>
public string LayoutString { get; set; } = string.Empty;
/// <summary>
/// Символ начала имени свойства
/// </summary>
public string StartSymbol { get; set; } = string.Empty;
/// <summary>
/// Символ конца имени свойства
/// </summary>
public string EndSymbol { get; set; } = string.Empty;
/// <summary>
/// Паттерн записи свойства
/// </summary>
public string Pattern => $"{StartSymbol}{"[\\w]+"}{EndSymbol}";
}
}

View File

@ -1,3 +1,4 @@
using Components.VisualComponents.HelperModels;
using WinForms.DataModels; using WinForms.DataModels;
namespace WinForms namespace WinForms
@ -20,7 +21,11 @@ namespace WinForms
customTextBox.DatePattern = @"^(\d{2}.\d{2}.\d{4})$"; customTextBox.DatePattern = @"^(\d{2}.\d{2}.\d{4})$";
customListBox.SetLayoutInfo("Čě˙ *Name* Ôŕěčëč˙ *Surname*", "*", "*"); CustomListBoxConfig config = new();
config.LayoutString = "Èìÿ {Name} Ôàìèëèÿ {Surname}";
config.StartSymbol = "{";
config.EndSymbol = "}";
customListBox.SetConfig(config);
} }
/// <summary> /// <summary>