COP_labs/Labs/ObjectsListBox.cs

188 lines
8.4 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 DocumentFormat.OpenXml.ExtendedProperties;
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;
using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace Labs
{
public partial class ObjectsListBox : UserControl
{
public ObjectsListBox()
{
InitializeComponent();
}
//макетная строка
private string templateLine;
//начальный символ для поиска свойств
private char startSymbol;
//конечный символ для поиска свойств
private char endSymbol;
public void SetTemplateInfo(string template, char start, char end)
{
if (template == null || start == null || end == null)
{
return;
}
templateLine = template;
startSymbol = start;
endSymbol = end;
}
//свойство для получения/установки индекса выбранной строки
public int SelectedIndex
{
get
{
return listBox.SelectedIndex;
}
set
{
if (listBox.SelectedItems.Count != 0)
{
listBox.SelectedIndex = value;
}
}
}
//параметризованный метод для получения объекта из выбранной строки
//T - класс, у которого есть пустой конструктор для возмож-ти создания экземпляра без параметров
public T GetObjectFromLine<T>() where T : class, new()
{
string SelectedLine = "";
if (listBox.SelectedIndex != -1)
{
SelectedLine = listBox.SelectedItem.ToString();
}
char[] symbols = { startSymbol, endSymbol };
//слова из шаблонной строки
string[] wordsInTemplate = templateLine.Split(symbols, StringSplitOptions.RemoveEmptyEntries);
//постоянные слова
List<string> constantWords = new List<string>();
//заполнение списка постоянных слов из шаблонной строки (с самого первого каждые 2 слова)
for (int i = 1; i < wordsInTemplate.Length; i+=2)
{
constantWords.Add(wordsInTemplate[i]);
}
//индексы постоянных слов
List<int> startsOfConstant = new List<int>();
string curString = SelectedLine;
int curIndex = 0;
foreach (string constantWord in constantWords)
{
//Нахождение const слова целиком с текущего индекса curIndex (в подстроке, начин. с curIndex)
int indexOfConstant = curString.IndexOf(constantWord, 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)
{
//если индекс до индекса j-го по счёту константного слова, т.е. это слово-значение
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>();
for (int i = 0; i < wordsInTemplate.Length; i+=2)
{
propertyNames.Add(wordsInTemplate[i]);
}
//Создание нужного объекта. Получение его типа для присваивание ему полученных ранее значений
T curObject = new T();
Type curType = curObject.GetType();
for (int i = 0; i < propertyNames.Count; i++)
{
//получение свойства объекта
PropertyInfo propertyInfo = curType.GetProperty(propertyNames[i]);
//получение значения свойства из списка полученных значений
string curVal = values[i];
propertyInfo.SetValue(curObject, Convert.ChangeType(curVal, propertyInfo.PropertyType));
}
return curObject;
}
//параметризованный метод заполнения списка, у которого в передаваемых параметрах идет список объектов некого класса
public void Fill<T>(List<T> objects)
{
//если макетрная строка/пограничные символы не указаны
if (templateLine == null || startSymbol == null || endSymbol == null)
{
return;
}
//если в строке нет пограничных символов
if (!templateLine.Contains(startSymbol) || !templateLine.Contains(endSymbol))
{
return;
}
//каждый объект в переданном списке (каждая строчка в конечном списке)
foreach (var obj in objects)
{
//строка, которая будет отображаться в (сначала похожа на шаблон, потом заполняются значения)
string str = templateLine;
//каждое св-во объекта (в 1 строчке)
foreach (var prop in obj.GetType().GetProperties())
{
//как выглядит место, куда надо вставить значение в шаблонной строке (обозначенное начальным и конечным символом, названием свойства)
string str1 = $"{startSymbol}" + $"{prop.Name}" + $"{endSymbol}";
//в шаблонной строке на помеченное место вставляем его значение
str = str.Replace(str1, prop.GetValue(obj).ToString());
}
listBox.Items.Add(str);
}
}
}
}