дай бог примут первую лабу

This commit is contained in:
bulatova_karina 2024-09-30 21:32:40 +04:00
parent 6999216c4a
commit 9aaa1cb436
2 changed files with 265 additions and 64 deletions

View File

@ -4,7 +4,9 @@ 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;
@ -12,12 +14,33 @@ namespace Components.Components
{
public partial class UserListBoxObject : UserControl
{
private string? _template;
public UserListBoxObject()
{
InitializeComponent();
}
//макетная строка
private string templateLine;
private char? _fromChar;
//начальный символ для поиска свойств
private string startSymbol;
private char? _toChar;
//конечный символ для поиска свойств
private string endSymbol;
public void SetTemplateInfo(string template, string start, string end)
{
if (template == null || start == null || end == null)
{
return;
}
templateLine = template;
startSymbol = start;
endSymbol = end;
}
//свойство для получения/установки индекса выбранной строки
public int SelectedIndex
{
get
@ -26,73 +49,251 @@ namespace Components.Components
}
set
{
listBoxObj.SelectedIndex = value;
}
}
public UserListBoxObject()
{
InitializeComponent();
}
public void SetParams(string template, char fromChar, char toChar)
{
_template = template;
_fromChar = fromChar;
_toChar = toChar;
}
public T? GetObject<T>()
{
if (listBoxObj.SelectedIndex == -1 || string.IsNullOrEmpty(_template) || !_fromChar.HasValue || !_toChar.HasValue)
throw new ArgumentException("Не хватает данных");
var type = typeof(T);
var properties = type.GetProperties();
var curObject = Activator.CreateInstance(type);
string[] wordsTemplate = _template.Split(' ');
string[] words = listBoxObj.SelectedItem.ToString().Split(' ');
for (int i = 0; i < wordsTemplate.Length; i++)
{
string word = wordsTemplate[i];
if (word.Contains(_fromChar.Value) && word.Contains(_toChar.Value))
if (listBoxObj.SelectedItems.Count != 0)
{
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));
listBoxObj.SelectedIndex = value;
}
}
return (T?)curObject;
}
public void AddItems<T>(List<T> items)
where T : class
//параметризованный метод для получения объекта из выбранной строки
//T - класс, у которого есть пустой конструктор для возмож-ти создания экземпляра без параметров
public T GetObjectFromLine<T>() where T : class, new()
{
if (string.IsNullOrEmpty(_template) || !_fromChar.HasValue || !_toChar.HasValue)
throw new ArgumentException("Не хватает данных");
listBoxObj.Items.Clear();
var type = typeof(T);
var properties = type.GetProperties();
foreach (T item in items)
string SelectedLine = "";
if (listBoxObj.SelectedIndex != -1)
{
string result = _template;
foreach (var property in properties)
SelectedLine = listBoxObj.SelectedItem.ToString();
}
//слова из шаблонной строки
string[] wordsInTemplate = templateLine.Split(' ');
//постоянные слова
List<string> constantWords = new List<string>();
foreach (string word in wordsInTemplate)
{
if (word.StartsWith(startSymbol))
{
string search = _fromChar.Value + property.Name + _toChar.Value;
result = result.Replace(search, property.GetValue(item)?.ToString() ?? "");
continue;
}
listBoxObj.Items.Add(result);
constantWords.Add(word);
}
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);
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());
}
//ВАРИАНТ 2, ПОСЛОВНО
//слова выборанной строки
//string[] wordsInSelectedLine = SelectedLine.Split(' ');
//StringBuilder curValue = new StringBuilder();
//for(int i = 0; i < wordsInSelectedLine.Length; i++)
//{
// string curWord = wordsInSelectedLine[i];
// //Если слово не в списке постоянных
// if (!constantWords.Contains(curWord))
// {
// //добавить текущее слово к значению (в значении может быть несколько слов (строковые значения с пробелами))
// curValue.Append(curWord + " ");
// //если следующее слово - постоянное
// if (i < wordsInSelectedLine.Length - 1 && constantWords.Contains(wordsInSelectedLine[i+1]))
// {
// //в список значений добавить текущее слово-значение (убирая пробелы в конце и все знаки пунктуации
// values.Add(Regex.Replace(curValue.ToString().TrimEnd(), @"[^\w\s]", ""));
// curValue.Clear();
// }
// //если больше слов нет, а последнее не было постоянным (т.е. надо запомнить)
// if (i == wordsInSelectedLine.Length - 1 && curValue.Length > 0)
// {
// values.Add(Regex.Replace(curValue.ToString().TrimEnd(), @"[^\w\s]", ""));
// }
// }
//}
//ВАРИАНТ 3 (должен точно работать)
//Заполнять при заполнении (метод Fill) приватный список, где символы начала и конца остались
//Выводить без спец. символов, работать с тем, где есть спец. символы (старый код)
//Названия свойств из шаблона
List<string> propertyNames = new List<string>();
foreach (string word in templateLine.Split(" "))
{
if (word.Contains(startSymbol))
{
propertyNames.Add(Regex.Replace(word.Replace(startSymbol, "").Replace(endSymbol, ""), @"[^\w\s]", ""));
}
}
curIndex = 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());
}
//ВАРИАНТ 2, ПОСЛОВНО
//слова выборанной строки
//string[] wordsInSelectedLine = SelectedLine.Split(' ');
//StringBuilder curValue = new StringBuilder();
//for(int i = 0; i < wordsInSelectedLine.Length; i++)
//{
// string curWord = wordsInSelectedLine[i];
// //Если слово не в списке постоянных
// if (!constantWords.Contains(curWord))
// {
// //добавить текущее слово к значению (в значении может быть несколько слов (строковые значения с пробелами))
// curValue.Append(curWord + " ");
// //если следующее слово - постоянное
// if (i < wordsInSelectedLine.Length - 1 && constantWords.Contains(wordsInSelectedLine[i+1]))
// {
// //в список значений добавить текущее слово-значение (убирая пробелы в конце и все знаки пунктуации
// values.Add(Regex.Replace(curValue.ToString().TrimEnd(), @"[^\w\s]", ""));
// curValue.Clear();
// }
// //если больше слов нет, а последнее не было постоянным (т.е. надо запомнить)
// if (i == wordsInSelectedLine.Length - 1 && curValue.Length > 0)
// {
// values.Add(Regex.Replace(curValue.ToString().TrimEnd(), @"[^\w\s]", ""));
// }
// }
//}
//ВАРИАНТ 3 (должен точно работать)
//Заполнять при заполнении (метод Fill) приватный список, где символы начала и конца остались
//Выводить без спец. символов, работать с тем, где есть спец. символы (старый код)
//Названия свойств из шаблона
//List<string> propertyNames = new List<string>();
foreach (string word in templateLine.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;
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());
}
listBoxObj.Items.Add(str);
}
}
}

View File

@ -20,10 +20,10 @@ namespace WinForms
InitializeComponent();
list = new List<string>();
list.AddRange(new string[] { "слон", "волк", "кролик" });
listBoxObj.SetParams("Имя: {FirstName}, Фамилия: {LastName}. {Experience} ({Age}) лет.", '{', '}');
listBoxObj.AddItems(new List<Worker> { new() { Name = "Иван", LastName = "Иванов", Age = 23, Experience = 5 },
//listBoxObj.SetParams("Имя: {FirstName}, Фамилия: {LastName}. {Experience} ({Age}) лет.", '{', '}');
/*listBoxObj.AddItems(new List<Worker> { new() { Name = "Иван", LastName = "Иванов", Age = 23, Experience = 5 },
new() { Name = "Егор", LastName = "Булаткин", Age = 30, Experience = 10 },
new() { Name = "Арбуз", LastName = "Арбуз", Age = 40, Experience = 7 } });
new() { Name = "Арбуз", LastName = "Арбуз", Age = 40, Experience = 7 } });*/
dropDownList.LoadValues(new List<string>() { "котенок", "собачка", "лиса" });
emailTextBox.Pattern = @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$";
}