PIbd-32_Safiulova_K.N._COP/COP_7/ListBoxMany.cs
2024-10-01 11:30:27 +04:00

169 lines
7.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Components
{
public partial class ListBoxMany : UserControl
{
private string _templateString;
private string __startSymbol;
private string __endSymbol;
private List<string> constantWords = new List<string>();
private List<string> values = new List<string>();
public ListBoxMany()
{
InitializeComponent();
}
//Устанавливает шаблонную строку и символы начала и конца переменной.
public void SetTemplateString(string templateString, string _startSymbol, string _endSymbol)
{
if (string.IsNullOrEmpty(templateString) || string.IsNullOrEmpty(_startSymbol) || string.IsNullOrEmpty(_endSymbol))
{
throw new ArgumentNullException("Введены не все значения");
}
_templateString = templateString;
__startSymbol = _startSymbol;
__endSymbol = _endSymbol;
}
//Свойство для получения или установки индекса выбранной строки в ListBox.
//Если текущий индекс не равен 0, то устанавливается новый индекс.
public int SelectedIndex
{
get { return listBox.SelectedIndex; }
set
{
if (listBox.SelectedIndex != 0)
{
listBox.SelectedIndex = value;
}
}
}
//параметризованный метод для получения объекта из выбранной строки
//T - класс, у которого есть пустой конструктор для возмож-ти создания экземпляра без параметров
public T GetObjectFromLine<T>() where T : class, new()
{
string SelectedLine = "";
if (listBox.SelectedIndex != -1)
{
SelectedLine = listBox.SelectedItem.ToString();
}
//слова из шаблонной строки
string[] wordsInTemplate = _templateString.Split(' ');
//постоянные слова
List<string> constantWords = new List<string>();
foreach (string word in wordsInTemplate)
{
if (word.StartsWith(__startSymbol))
{
continue;
}
constantWords.Add(word);
}
List<int> startsOfConstant = new List<int>();
string curString = SelectedLine;
int curIndex = 0;
foreach (string constantWord in constantWords)
{
//Нахождение const слова целиком с текущего индекса curIndex (в подстроке, начин. с curIndex)
Match match = Regex.Match(curString.Substring(curIndex), $@"\b{constantWord}\b");
int indexOfConstant = match.Index + curIndex;
startsOfConstant.Add(indexOfConstant);
curIndex = indexOfConstant + constantWord.Length;
}
//Слова, являющиеся значениями полей
List<string> values = new List<string>();
curIndex = 0;
int j = 0;
while (curIndex < SelectedLine.Length && j < constantWords.Count)
{
if (curIndex < startsOfConstant[j])
{
string value = SelectedLine.Substring(curIndex, startsOfConstant[j] - curIndex);
//если строка не пустая (не null и не одни пробелы)
if (!string.IsNullOrWhiteSpace(value))
{
//добавить её и убрать лишние пробелы перед значением и после (могут быть, могут не быть)
values.Add(value.TrimStart().TrimEnd());
}
}
curIndex = startsOfConstant[j] + constantWords[j].Length;
j++;
}
//Если текущий индекс не последний, а все постоянные слова закончились, значит до конца строки - значение
if (curIndex < SelectedLine.Length)
{
values.Add(SelectedLine.Substring(curIndex).TrimStart().TrimEnd());
}
List<string> propertyNames = new List<string>();
foreach (string word in _templateString.Split(" "))
{
if (word.Contains(__startSymbol))
{
propertyNames.Add(Regex.Replace(word.Replace(__startSymbol, "").Replace(__endSymbol, ""), @"[^\w\s]", ""));
}
}
//Получение свойств объекта и присваивание ему полученных раньше значений
T curObject = new T();
Type curType = curObject.GetType();
char[] punctuations = { '.', ',', '?', '!', ';', ':', '-', '\'', '\"' };
for (int i = 0; i < propertyNames.Count; i++)
{
PropertyInfo propertyInfo = curType.GetProperty(propertyNames[i]);
string curVal = values[i];
//если был вплотную знак препинания (в конце значения) - убрать (чтобы не было исключения)
if (punctuations.Contains(curVal[curVal.Length - 1]))
{
curVal = curVal.Remove(curVal.Length - 1);
}
var convertedValue = Convert.ChangeType(curVal, propertyInfo.PropertyType);
propertyInfo.SetValue(curObject, convertedValue);
}
return curObject;
}
//Заполняет строку в ListBox на основе значения свойства объекта dataObject.
//Если строка с указанным индексом отсутствует, она добавляется на основе шаблонной строки.
public void FillProperty<T>(T dataObject, int rowIndex, string propertyName)
{
while (listBox.Items.Count <= rowIndex)
{
listBox.Items.Add(_templateString);
}
string row = listBox.Items[rowIndex].ToString();
PropertyInfo propertyInfo = dataObject.GetType().GetProperty(propertyName);
if (propertyInfo != null)
{
object propertyValue = propertyInfo.GetValue(dataObject);
row = row.Replace($"{__startSymbol}{propertyName}{__endSymbol}", propertyValue.ToString());
listBox.Items[rowIndex] = row;
}
}
}
}