Предыдущая лекция | | Следующая лекция :----------------:|:----------:|:----------------: [Подсветка элементов по условию. Дополнительные выборки.Массовая смена цены продукции.](./cs_pagination2.md) | [Содержание](../readme.md#c-и-mysql) | [Вывод списка материалов продукта. CRUD материалов продукта](./cs_product_material.md) # Добавление/редактирование продукции * [Создание окна редактирования продукции](#создание-окна-редактирования-продукции) * [Открытие окна редактирования для существующей и новой продукции](#открытие-окна-редактирования-для-существующей-и-новой-продукции) * [Проверки перед сохранением продукта](#проверки-перед-сохранением-продукта) * [Удаление продукции](#удаление-продукции) >Необходимо добавить возможность редактирования данных существующей продукции, а также добавление новой продукции в новом окне - форме для добавления/редактирования продукции. > >Переходы на данное окно должны быть реализованы из главной формы списка: для редактирования - при нажатии на конкретный элемент, для добавления - при нажатии кнопки “Добавить продукцию”. > >На форме должны быть предусмотрены следующие поля: артикул, наименование, тип продукта (выпадающий список), изображение, количество человек для производства, номер производственного цеха, минимальная стоимость для агента и подробное описание (с возможностью многострочного ввода). > >Также необходимо реализовать вывод списка материалов, используемых при производстве продукции, с указанием количества. В список можно добавлять новые позиции и удалять существующие. При добавлении материалы должны выбираться из выпадающего списка с возможностью поиска по наименованию. > >При открытии формы для редактирования все поля выбранного объекта должны быть подгружены в соответствующие поля из базы данных, а таблица заполнена актуальными значениями. > >Стоимость продукции может включать сотые части, а также не может быть отрицательной. Система должна проверять существование продукта с введенным артикулом и не давать использовать один артикул для нескольких продуктов. > >Пользователь может добавить/заменить изображение у продукции. > >Для того чтобы администратор случайно не изменял несколько продуктов, предусмотрите невозможность открытия более одного окна редактирования. > >В окне редактирования продукта должна присутствовать кнопка “Удалить”, которая удаляет продукт из базы данных. При этом должны соблюдаться следующие условия. Если у продукта есть информация о материалах, используемых при его производстве, или история изменения цен, то эта информация должна быть удалена вместе с продуктом. Но если у продукта есть информация о его продажах агентами, то удаление продукта из базы данных должно быть запрещено. После удаления продукта система должна сразу вернуть пользователя обратно к списку продукции. > >После редактирования/добавления/удаления продукции данные в окне списка продукции должны быть обновлены. Критерий | Баллы ---------|:---: Реализован переход на окно добавления | 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; } ``` 1. В разметке окна вставьте аттрибут *Name* ```xml ``` 1. В конструктор окна добавьте параметр типа **Product**, присвойте его ранее объявленному свойству. Задайте заголовок окна: ```cs public EditProductWindow(Product editProduct) { InitializeComponent(); DataContext = this; currentProduct = editProduct; root.Title = currentProduct.ID == 0 ? "Новый продукт" : "Редактирование продукта"; } ``` 1. В разметке окна редактирования продукции создайте сетку из трёх колонок: в первой у нас будет изображение, во второй редактируемые поля продукта, а в третей список материалов ```xml ``` 1. Во вторую колонку добавьте **StackPanel** с границами (чтобы визуальные компоненты не прилипали к границам окна) и в этом списке разместите редактируемые элементы >На форме должны быть предусмотрены следующие поля: _артикул_, _наименование_, _тип продукта_ (выпадающий список), _изображение_, _количество человек для производства_, _номер производственного цеха_, _минимальная стоимость для агента_ и _подробное описание_ ```xml ``` Обычные поля (числовые и строковые) наклепайте по шаблону сами, а я подробнее остановлюсь на полях: _тип продукта_, _изображение_ и _описание_: * Выбор типа продукта из списка В классе окна объявляем свойство _productTypeList_ - список типов продукции ```cs public List productTypeList { get; set; } ``` И в конструкторе получаем его из БД: ```cs productTypeList = Globals.dataProvider.getProductTypes().ToList(); ``` В вёрстке окна редактирования продукции мы можем использовать выпадающий список, атрибут _SelectedIndex_ которого позволяет отобразить **текущее** значение редактируемого элемента ```xml ``` Чтобы получить индекс (позицию в списке) текущего продукта нужно после получения списка типов продуктов добавить поиск: ```cs // в классе окна public int selectedProductIndex { get; set; } = -1; ... // в конструкторе окна if (currentProduct.ID > 0) { selectedProductIndex = productTypeList.FindIndex(pt => pt.ID == currentProduct.ProductTypeID); } ``` * смена изображения продукции Вывод изображения производится как и в главном окне ```xml ``` А для смены изображения используем стандартный диалог открытия файлов, повесив его на кнопку *Сменить картинку* (кнопку добавьте сами в центральную колонку) Обработчик кнопки: ```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