Подсветка элементов по условию. Дополнительные выборки.Массовая смена цены продукции. Содержание Основы языка Kotlin
# Добавление/редактирование продукции >Необходимо добавить возможность редактирования данных существующей продукции, а также добавление новой продукции в новом окне - форме для добавления/редактирования продукции. > >Переходы на данное окно должны быть реализованы из главной формы списка: для редактирования - при нажатии на конкретный элемент, для добавления - при нажатии кнопки “Добавить продукцию”. > >На форме должны быть предусмотрены следующие поля: артикул, наименование, тип продукта (выпадающий список), изображение, количество человек для производства, номер производственного цеха, минимальная стоимость для агента и подробное описание (с возможностью многострочного ввода). > >Также необходимо реализовать вывод списка материалов, используемых при производстве продукции, с указанием количества. В список можно добавлять новые позиции и удалять существующие. При добавлении материалы должны выбираться из выпадающего списка с возможностью поиска по наименованию. > >При открытии формы для редактирования все поля выбранного объекта должны быть подгружены в соответствующие поля из базы данных, а таблица заполнена актуальными значениями. > >Стоимость продукции может включать сотые части, а также не может быть отрицательной. Система должна проверять существование продукта с введенным артикулом и не давать использовать один артикул для нескольких продуктов. > >Пользователь может добавить/заменить изображение у продукции. > >Для того чтобы администратор случайно не изменял несколько продуктов, предусмотрите невозможность открытия более одного окна редактирования. > >В окне редактирования продукта должна присутствовать кнопка “Удалить”, которая удаляет продукт из базы данных. При этом должны соблюдаться следующие условия. Если у продукта есть информация о материалах, используемых при его производстве, или история изменения цен, то эта информация должна быть удалена вместе с продуктом. Но если у продукта есть информация о его продажах агентами, то удаление продукта из базы данных должно быть запрещено. После удаления продукта система должна сразу вернуть пользователя обратно к списку продукции. > >После редактирования/добавления/удаления продукции данные в окне списка продукции должны быть обновлены. Критерий | Баллы ---------|:---: Реализован переход на окно добавления | 0.1 Реализован переход на окно редактирования выбранного объекта | 0.2 Присутствуют все поля для заполнения | 0.5 При редактировании продукции в поля для ввода загружены данные из БД | 0.3 Выбор типа продукта реализован в виде выпадающего списка со значениями из БД | 0.3 Для ввода описания продукции предусмотрено многострочное поле для ввода | 0.2 ***Реализован список используемых материалов для текущего продукта*** | 0.3 ***В списке присутствует название материала и используемое количество*** | 0.2 ***При редактировании продукции список материалов заполнен значениями из БД*** | 0.2 ***В список можно добавлять новые позиции*** | 0.3 ***Из списка можно удалять существующие позиции*** | 0.2 ***При добавлении материалы выбираются из выпадающего списка со значениями из БД*** | 0.3 ***В списке материалов реализована возможность поиска по наименованию*** | 0.2 ***Список используемых материалов сохраняется в БД при добавлении*** | 0.5 ***Список используемых материалов сохраняется в БД при редактировании*** | 0.5 Стоимость продукции не может быть отрицательной | 0.1 Стоимость продукции записывается только с точностью до сотых | 0.2 Реализована проверка артикула на уникальность | 0.3 Есть возможность выбрать изображение | 0.2 Изображение продукции подгружается из БД при редактировании | 0.2 Есть возможность заменить изображение | 0.1 Данные при добавлении сохраняются в БД | 0.5 Данные при редактировании изменяются в БД | 0.5 Открывается только одно окно редактирования | 0.1 *Реализовано удаление выбранного продукта, у которого не заполнен список используемых материалов* | 0.2 *Реализовано удаление продукта вместе с информацией об используемых материалах* | 0.5 *Запрещено удаление продукта, по которому были выполнены продажи агентом* | 0.3 *После удаления реализован автоматический переход обратно в список* | 0.1 После закрытия окна данные в таблице обновляются | 0.3 **Итого** | **7.9** # Создание окна редактирования продукции Для добавления и редактирования мы будем использовать одно и то же окно. Название окна будем вычислять по наличию ID у продукции (у новой записи это поле = 0) 1. Создайте новое окно: **EditProductWindow** (в папке **Windows** - не забываем про логическую структуру проекта) 1. В классе окна **EditProductWindow** добавьте свойство *CurrentProduct*, в котором будет храниться добавляемый/редактируемый экземпляр продукции: ```cs public Product CurrentProduct { get; set; } ``` И геттер для названия окна: ```cs public string WindowName { get { return CurrentProduct.Id == 0 ? "Новый продукт" : "Редактирование продукта"; } } ``` 1. В конструктор окна добавьте параметр типа **Product** и присвойте его ранее объявленному свойству: ```cs public EditWindow(Product EditProduct) { InitializeComponent(); DataContext = this; CurrentProduct = EditProduct; } ``` 1. В разметке окна вместо фиксированного названия вставьте привязку к свойству *WindowName* ```xml ``` 1. В окне редактирования продукции создайте сетку из трёх колонок: в первой у нас будет изображение, во второй редактируемые поля продукта, а в третей список материалов ```xml ``` 1. Во вторую колонку добавьте **StackPanel** с границами (чтобы визуальные компоненты не прилипали к границам окна) и в этом списке разместите редактируемые элементы >На форме должны быть предусмотрены следующие поля: артикул, наименование, тип продукта (выпадающий список), изображение, количество человек для производства, номер производственного цеха, минимальная стоимость для агента и подробное описание ```xml ``` Обычные поля наклепайте по шаблону сами, а я подробнее остановлюсь на полях: *тип продукта*, *изображение* и *описание*: * Выбор типа продукта из списка В классе окна объявляем свойство *ProductTypes* - список типов продукции ```cs public IEnumerable ProductTypeList { get; set; } ``` И в конструкторе получаем его из контекста БД: ```cs using (var context = new ksmirnovContext()) { ProductTypeList = context.ProductTypes.ToList(); } ``` В вёрстке окна редактирования продукции мы можем использовать выпадающий список, атрибут *SelectedItem* которого позволяет отобразить текущее значение редактируемого элемента ```xml ``` >Из документации: *Класс ComboBox выполняет поиск указанного объекта с помощью **IndexOf** метода. Этот метод использует **Equals** метод для определения равенства*. А метод **Equals** сравнивает объекты по уникальному идентификатору, т.е. свойство **ProductType** у экземпляра продукции НЕ РАВНО экземпляру элемента списка *ProductTypeList* Чтобы исправить эту неприятность нужно переопределить метод **Equals** у класса **ProductType**: ```cs public override bool Equals(object obj) { return (obj != null) && (obj is ProductType) && (this.Id == (obj as ProductType).Id); } ``` Здесь мы проверяем определён ли вообще объект (у нового продукта его ещё нет), нужного ли он типа и совпадет ли его **Id** с **Id** текущего типа продукции * смена изображения продукции Вывод изображения производится как и в главном окне ```xml ``` А для смены изображения используем стандартный диалог Windows, повесив его на кнопку *Сменить картинку* (кнопку добавьте сами в **StackPanel**) Обработчик кнопки: ```cs private void ChangeImage_Click(object sender, RoutedEventArgs e) { OpenFileDialog GetImageDialog = new OpenFileDialog(); // задаем фильтр для выбираемых файлов // до символа "|" идет произвольный текст, а после него шаблоны файлов разделенные точкой с запятой GetImageDialog.Filter = "Файлы изображений: (*.png, *.jpg)|*.png;*.jpg"; // чтобы не искать по всему диску задаем начальный каталог GetImageDialog.InitialDirectory = Environment.CurrentDirectory; if (GetImageDialog.ShowDialog() == true) { // перед присвоением пути к картинке обрезаем начало строки, т.к. диалог возвращает полный путь CurrentProduct.Image = GetImageDialog.FileName.Substring(Environment.CurrentDirectory.Length); // обратите внимание, это другое окно и другой Invalidate, который реализуйте сами Invalidate(); } } ``` * Многострочное описание Тут просто - разрешаем переносы и задаем высоту элемента ```xml