Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/34: Рейтинг темы: голосов - 34, средняя оценка - 4.91
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468

Приложение MVVM. Диалог добавления/редактирования товара: получение данных, вызов, взаимодействие с VM и прочее

09.03.2023, 14:42. Показов 9309. Ответов 207
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В этой теме обсуждается только вопросы по реализации Диалога редактирования товара и связанных с этим действиях .
Основная тема: Приложение MVVM. VMs и навигация
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я изначально предлагал другой вариант, гораздо проще реализуемый:
Просто в одном варианте задания были требования по реализации редактирования с помощью контекстного меню. Вот поэтому я и заинтересовался. К тому же хотелось получить какой-то опыт работы с ним

Добавлено через 3 минуты
Меня интересует маппер. Он инициализирует свойства составного типа такие как Manufacturer?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.03.2023, 14:42
Ответы с готовыми решениями:

Приложение MVVM. Контекстное меню (удаление, редактирование) для элемента (Товара) в ListBox
Да, для добавления будет отдельная кнопка где-то сверху. А для редактирования давайте создадим контекстное меню для каждого элемента. Хотя...

Взаимодействие баз данных с MVVM
Мне посоветовали завернуть роботу с базами в класс сервис и работать с ней через биндинги вьюшки, но дело в том что я не совсем понимаю что...

Взаимодействие с базой данных в MVVM
У меня есть класс, в котором реализована логика взаимодействия с БД, все таблицы хранятся в этой структуре в памяти. Этот класс...

207
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
23.03.2023, 07:17  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Не так всё просто, но попробуйте.
А, ну да, значение введется и в случае с Binding.DoNothing оно просто в источнике не поменяется, останется старым, так?

Добавлено через 1 минуту
А в таком случае будет вызвано перечитывание значения из get? Мне кажется нет
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
23.03.2023, 08:37
INexteR, изменил цифровые конвертеры на общий.
И вынес валидацию из сеттеров.
Посмотрите фиксацию.

Добавлено через 1 минуту
Цитата Сообщение от INexteR Посмотреть сообщение
А в таком случае будет вызвано перечитывание значения из get? Мне кажется нет
Не будет.
Перечитывание возникает после присвоения значения свойства.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
24.03.2023, 08:28
INexteR, я ещё подправил контекстное меню.
1
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
26.03.2023, 15:01  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
я ещё подправил контекстное меню.
Почему вас не устраивает просто при загрузке в обработчике произвести настройку один раз?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
26.03.2023, 17:03
Цитата Сообщение от INexteR Посмотреть сообщение
Почему вас не устраивает просто при загрузке в обработчике произвести настройку один раз?
Потому что это загрузка Окна.
Окно не должно отвечать по функционалу за такие вещи.
В данном случае у вас всё сделано "в одной каше", но "по взрослому" Окно разбивается на Регионы.
В данном случае, будет выделен регион Списка и в неё Регионы элементов Списка.
Контекстное меню - это часть региона элемента списка.
Окно ничего не знает о регионе третьего уровня вложенности и не сможет там ничего настраивать.

Добавлено через 1 минуту
В текущей разметке перенесите Контекстное Меню в ресурсы Шаблона Элемента Товара и попробуйте его настроить.
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
31.03.2023, 15:25  [ТС]
Элд Хасп, Отправка объекта IList с выбранными элементами в ViewModel почему тогда Вы тут ничего против не сказали? Тоже используется обработчик события Loaded
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
31.03.2023, 17:06
Цитата Сообщение от INexteR Посмотреть сообщение
почему тогда Вы тут ничего против не сказали?
Он же сам написал:
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
... когда лень писать кучу свойств в VM, потом их привязывать ...
Что здесь написать? "Не надо лениться!"?
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
31.03.2023, 19:33  [ТС]
Элд Хасп, понятно. Но только в моем случае я не поленился, а попытался избежать ненужной работы, или, как Вы говорите, сэкономил доллар
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
02.04.2023, 10:00  [ТС]
Элд Хасп, а Вы же не объединили обработчик PreviewTextInput с конвертером?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
02.04.2023, 12:42
Цитата Сообщение от INexteR Посмотреть сообщение
а Вы же не объединили обработчик PreviewTextInput с конвертером?
Нет.
Мне не приходи в голову как это сделать, чтобы упростить, а не усложнить.
Упростить XAML можно но Шарп резко осложнится.
Проблема в том, что Binding защищён от изменений и от него нельзя сделать производный класс...

Вернее, защищён не он, а его метод ProvideValue и нельзя его переопределить.
А информацию об элементе, который использует Binding можно получить только из этого метода.
Поэтому придётся делать фактически свой кастомный Binding "с нуля". А это ОЧЕНЬ сложно.
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
02.04.2023, 13:51  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Поэтому придётся делать фактически свой кастомный Binding "с нуля". А это ОЧЕНЬ сложно.
Ну это вообще не вариант, даже не думайте о таком
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
02.04.2023, 13:57
Цитата Сообщение от INexteR Посмотреть сообщение
Ну это вообще не вариант, даже не думайте о таком
У меня есть библиотечный элемент: Непростое Решение для простой часто встречающейся задачи. Привязка TextBox к численному свойству [WPF, Элд Хасп]
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
12.04.2023, 21:20  [ТС]
Элд Хасп, в этой реализации осталась такая засечка, что на форме авторизации в текстовом блоке статус отображается как значение из перечисления. Тут нужен DictionaryConverter, верно?

Добавлено через 1 минуту
И вот я думаю, что хотел бы в следующей реализации испробовать подход с использованием DTO вместо интерфейсов. А также при редактировании я бы не хотел менять сущности целиком, а только свойства

Добавлено через 8 минут
Мне нужно создать новый проект. И он будет на порядок сложнее, чем тот, что мы делали на демоэкзамен. Сможете помочь с ним? Предметной областью будет являться санаторий. Там уже нужно будет добавлять и редактировать: клиентов, заказы, процедуры и проч. Первой проблемой для меня является создание правильной бд

Добавлено через 1 минуту
Элд Хасп, первоначально мой путь лежит через раздел баз данных и ADO, верно?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
12.04.2023, 21:34
Цитата Сообщение от INexteR Посмотреть сообщение
в этой реализации осталась такая засечка, что на форме авторизации в текстовом блоке статус отображается как значение из перечисления. Тут нужен DictionaryConverter, верно?
Или триггерами, или конвертерами. DictionaryConverter - это один из вариантов конвертера, чтобы делать новый "на каждый чих".

Цитата Сообщение от INexteR Посмотреть сообщение
И вот я думаю, что хотел бы в следующей реализации испробовать подход с использованием DTO вместо интерфейсов.
Допустимо.

Цитата Сообщение от INexteR Посмотреть сообщение
А также при редактировании я бы не хотел менять сущности целиком, а только свойства
Как?
VM отражает Модель, а не View.
Модель делает ПОПЫТКУ изменения в ХРАНИЛИЩЕ.
Если попытка удачна, то нужно уведомить своих потребителей об изменении.
Если уведомлять о замене сущности, то мы получаем новую сущность и целиком её отправляем потребителям.

А если уведомлять только об изменении одного из свойств, то придётся отправлять событие НА КАЖДОЕ изменённое свойство.
Это сложнее, объёмнее по коду как в Модели так и в её потребителях.
Я даже не знаю в каких сценариях это может быть эффективно.

Разве что огромные сущности, у которых одновременно может меняться одно-два свойства.
"Огромные" - это те которые в памяти занимают, наверное, сотни килобайт.
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
12.04.2023, 21:37  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А если уведомлять только об изменении одного из свойств, то придётся отправлять событие НА КАЖДОЕ изменённое свойство.
Просто сделать модель как таковую, которая реализует INPC
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
12.04.2023, 21:43
Цитата Сообщение от INexteR Посмотреть сообщение
Первой проблемой для меня является создание правильной бд
Архитектура БД важна. НО, мы же работаем с Моделью. В данном случае БЛ, кроме работы с Хранилищем, пости ничего не будет содержать. Поэтому архитектура данных Модели и архитектура БД (Хранилища) будут совпадать.
Но это частный случай.
В общем случае нужно создавать эффективную архитектуру Модели, а как ей удобно сохранять - это вторичный вопрос.

Цитата Сообщение от INexteR Посмотреть сообщение
первоначально мой путь лежит через раздел баз данных и ADO, верно?
Особенно если это многопользовательское приложение.
У вас какая задача стоит?

Добавлено через 4 минуты
Цитата Сообщение от INexteR Посмотреть сообщение
Просто сделать модель как таковую, которая реализует INPC
Не Модель, а сущность вы, наверное, имеете ввиду.

И посмотрите что вы получите.
ПЕРЕД обновлением БД, вы сначала изменяете сущность. И все изменения отразятся в View. Если сохранения не произойдёт, View, то разорвётся связь. В Хранилище будут одни данные, в Модели другие.

Если сохранять, и потом обновлять сущность, то придётся это делать отдельно для каждого свойства.
И что этим выиграется?
Только код станет объёмнее и запутанее.

Добавлено через 48 секунд
Если уже есть сохранённая сущность, зачем из неё данные переписывать в старую, если гораздо проще заменить их?
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
12.04.2023, 22:24  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Особенно если это многопользовательское приложение.
К счастью нет. Задача - проект на диплом. Там то же, что и на демоэкзамен, только несколько сущностей нужно охватить для работы с ними. И ещё нужно выводить некоторые данные в отчет - word/excel
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Не Модель, а сущность вы, наверное, имеете ввиду.
А вот и нет, модель. Например, возьмем то же свойство AuthorizationStatus. Мы не станем выделять событие StatusChanged, а просто заменим его на PropertyChanged и в сеттере свойства будем производить вызов. Далее VM подпишется на это событие и дальше пробросит к view

Добавлено через 9 минут
Цитата Сообщение от Элд Хасп Посмотреть сообщение
ПЕРЕД обновлением БД, вы сначала изменяете сущность. И все изменения отразятся в View. Если сохранения не произойдёт, View, то разорвётся связь. В Хранилище будут одни данные, в Модели другие.
Согласен, действительно ситуация тупиковая. Ну, видимо, тогда рассматривать данный вариант не стоит. Остается только замена интерфейсов на DTO
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
12.04.2023, 23:06
Если уже есть сохранённая сущность, зачем из неё данные переписывать в старую, если гораздо проще заменить их?
Цитата Сообщение от INexteR Посмотреть сообщение
, только несколько сущностей нужно охватить для работы с ними.
С несколькими изменяемыми сущностями сразу возникнет проблема уведомления об изменений сущности навигационного свойства.
Один из вариантов я вам показывал в теме Отправка объекта IList с выбранными элементами в ViewModel

Цитата Сообщение от INexteR Посмотреть сообщение
А вот и нет, модель. Например, возьмем то же свойство AuthorizationStatus. Мы не станем выделять событие StatusChanged, а просто заменим его на PropertyChanged
Можно.
У меня даже тема есть соответствующая INPC (INotifyPropertyChanged) и получение данных из Модели [WPF, Элд Хасп]
Но "поигравшись" с множеством различных реализаций, всё же приходишь к мнению, что INPC неудобен.
По сути он имеет преимущества только, если работа данными идёт с использованием рефлексии или чего-то близкого (привязки, например). Или когда очень много свойств и за всеми нужно следить по отдельности.
В Шарпе же принята всё таки строгая типизация и с ней лучше сочетаются индивидуальные события.
Например, при изменении статуса у нас же меняется не только Статус, но и текущий пользователь.
А ДЛЯ INPC нужно делать их раздельную прослушку.
1
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
14.04.2023, 14:15  [ТС]
Элд Хасп, то есть по вашему мнению существует только одна адекватная реализация редактирования - замена сущности целиком. Или есть ещё какие-то варианты?

И сейчас у меня ещё два вопроса возникло.

В одном из вариантов того же демо экзамена есть условие: если у товара имеется скидка, то основная цена должна быть перечеркнута и рядом дописана цена с учетом скидки. Здесь, я так понимаю, для перечеркивания нужно воспользоваться свойством TextBlock.TextDecorations. И раз тут нужно два текста, где один перечеркнут, другой нормальный, то потребуется 2 объекта Run. Проблема: нужно переменное число объектов в зависимости от условия. Хотел создать конвертер, который будет формировать эти объекты, но вот незадача: свойство TextBlock.Inlines не имеет метода задания и к тому же оно не DP. Как тут быть?

Второй вопрос. Вот, скажем, для тех же товаров задаю DataTemplate в ListBox. И весь этот шаблон создаю в элементе, производном от UserControl. Ну вот так мне захотелось писать, не прямо в DataTemplate, а в отдельном файле. И вопрос: почему я в моем шаблоне DataTemplate в DataTrigger не могу обратиться к именованному элементу, который находится в UserControl? Пример (содержимое UserControl):
XML
1
2
3
4
5
6
7
<Border BorderThickness="2"
        BorderBrush="Orange"
        CornerRadius="3">
    <StackPanel x:Name="sp" Margin="5">
        <TextBlock Text="{Binding Name}" />
    </StackPanel>
</Border>
И ListBox:
XML
1
2
3
4
5
6
7
8
9
10
11
12
<ListBox.ItemTemplate>
    <DataTemplate>
        <local:MyView />
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsActual}" Value="False">
                <Setter TargetName="sp"
                        Property="Background"
                        Value="Gray" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ListBox.ItemTemplate>
А вот так все в порядке, если не выносить разметку в отдельный UserControl:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<ListBox.ItemTemplate>
    <DataTemplate>
        <Border BorderThickness="2"
                BorderBrush="Orange"
                CornerRadius="3">
            <StackPanel x:Name="sp"
                        Margin="5">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </Border>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsActual}" Value="False">
                <Setter TargetName="sp"
                        Property="Background"
                        Value="Gray" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ListBox.ItemTemplate>
Добавлено через 7 минут
По поводу второго вопроса я сейчас подумал: причина в области видимости? Область видимости именованного StackPanel в UserControl отлична от той, когда он создается в шаблоне. То есть в шаблоне рассматриваются только те элементы, которые были созданы и именованы непосредственно в нем
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
14.04.2023, 20:40
Цитата Сообщение от INexteR Посмотреть сообщение
о есть по вашему мнению существует только одна адекватная реализация редактирования - замена сущности целиком. Или есть ещё какие-то варианты?
В данном случае, на мой взгляд, любой другой вариант будет менее оптимальным.
Но опять таки, не исключаю, что какой-то вариант мне просто не пришёл в голову.

Но есть же ещё и другие задачи.
Например, изменения могут накапливаться в Модели, и их сохранение происходит явным вызовом метода.
В таком случае, данные Модели уже не отражают Хранилище и здесь замена сущностей это не единственный вариант.

Например, игра. Есть предметы, поля, юниты и т.д. Всё это взаимодействует между собой. И если уменьшилось здоровье юнита, то можно только об этом и уведомить через INPC.

Добавлено через 3 минуты
Цитата Сообщение от INexteR Посмотреть сообщение
й, то потребуется 2 объекта Run. Проблема: нужно переменное число объектов в зависимости от условия.
Как я понимаю.
Есть текущая цена, которая отображается всегда.
В некоторых случаях есть предыдущая цена. Так как она есть не у всех товаров, то это должен быть Nullable<decimal>.

Что касается вывода, то можно сделать два TextBlock. Тот который выводит Nullable коллапсирует, если null.

Добавлено через 4 минуты
Цитата Сообщение от INexteR Посмотреть сообщение
причина в области видимости?
Всё верно.
Целевой элемент вычисляет ДО применения шаблона. И в это время он никак не может увидеть элементы вне себя.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.04.2023, 20:40

Создание базы данных с функциями ввода, вывода, редактирования, удаления или добавления данных
Задание заключается в создании базы данных с функциями ввода, вывода, редактирования, удаления или добавления данных. Написал программу и...

Формы редактирования, добавления данных
Добрый вечер, такой вопрос, мне нужно сделать для кнопок Редактировать и Добавить записи форму, но я немного не понимаю как это...

Форма для добавления, редактирования, удаления данных
Уважаемые форумчане, подскажите, как лучше сделать и правильнее! В форме &quot;Органы исполнительной власти&quot; в данной &quot;БД&quot;...

Пример добавления, удаления и редактирования данных в БД *.mbd
нужен пример добавления, удаления и редактирования данных в БД *.mbd через классы OleDbDataAdapter, OleDbConnection, DataSet. ...

Использование возможностей добавления, редактирования и удаления необходимых записей в базы данных
помогите дополнить код пожалуйста public partial class Form1 : Form { // здесь отмечаются переменные и методы внутри класса формы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
200
Ответ Создать тему
Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru