using System.Reflection; using System.Text.RegularExpressions; using static System.Net.Mime.MediaTypeNames; namespace ComponentsLibrary { public partial class ListBoxValues : UserControl { private string layoutString = string.Empty; private char startSymbol = '{'; private char endSymbol = '}'; private List items = new List(); private EventHandler? _getObject; public ListBoxValues() { InitializeComponent(); } //событие, вызываемое при выборе строки public event EventHandler GetObject { add { _getObject += value; } remove { _getObject -= value; } } private void listBox_SelectedIndexChanged(object sender, EventArgs e) { _getObject?.Invoke(this, e); } //Публичное свойство для установки и получения индекса выбранной строки (set, get). public int SelectedIndex { get { return listBox.SelectedIndex; } set { listBox.SelectedIndex = value; } } // Публичный метод для установки макетной строки и символов public void SetLayout(string layout, char startChar, char endChar) { layoutString = layout; startSymbol = startChar; endSymbol = endChar; } // Публичный метод для заполнения ListBox public void FillListBox(IEnumerable itemList) { listBox.Items.Clear(); items.Clear(); foreach (var item in itemList) { if (item != null) { items.Add(item); string displayText = CreateDisplayText(item); listBox.Items.Add(displayText); } } } // Метод для создания строки на основе макета private string CreateDisplayText(object item) { string text = layoutString; PropertyInfo[] properties = item.GetType().GetProperties(); foreach (var prop in properties) { string propertyValue = prop.GetValue(item)?.ToString() ?? string.Empty; text = text.Replace($"{startSymbol}{prop.Name}{endSymbol}", propertyValue); } return text; } // Публичный параметризованный метод для получения объекта из выбранной строки public T? GetSelectedItem() where T : new() { var selectedItem = listBox.SelectedItem; if (selectedItem != null) { string selectedString = selectedItem.ToString(); // Строка из ListBox T obj = new T(); PropertyInfo[] properties = typeof(T).GetProperties(); string pattern = layoutString; for (int i = 0; i < properties.Length; i++) { PropertyInfo prop = properties[i]; string propertyPattern = $"{startSymbol}{prop.Name}{endSymbol}"; if (i == properties.Length - 1) { pattern = pattern.Replace(propertyPattern, "(.*)"); } else { pattern = pattern.Replace(propertyPattern, "(.*?)"); } } Regex regex = new Regex(pattern); Match match = regex.Match(selectedString); if (match.Success) { for (int i = 0; i < properties.Length; i++) { string value = match.Groups[i + 1].Value; object convertedValue = Convert.ChangeType(value, properties[i].PropertyType); properties[i].SetValue(obj, convertedValue); } return obj; } } return default; } } }