|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||||||||||||||||
DI на этапе создания контрола из XAML29.10.2020, 00:47. Показов 3469. Ответов 45
Метки нет (Все метки)
Есть простейший ContentControl, расположенный в какой-то вспомогательной общей библиотеке:
И далее этому экземпляру 'ViewModelControl' в некий момент в рантайме приходит событие 'OnViewModelChanged' и ему нужно через 'ViewService', для текущего типа экземлпяра 'ViewModel': 1. Найти XAML, который сопоставлен данной ViewModel (логика сопоставления известна только уровню приложения, т.е. там, где происходит 'Application.LoadComponent'). 2. Cоздать UserControl на базе этого XAML. Вопрос: как наименее затратно по коду/времени и не нарушая иерархию зависимостей выдать всем экземплярам 'ViewModelControl' (созданным в процессе создания контрола на базе XAML) экземпляр сервиса 'IViewService' (реализованого на уровне приложения, которое всё это использует)? Пока что единственный вариант, что удалось придумать - после выполнения 'Application.LoadComponent', пройтись при при помощи 'LogicalTreeHelper' по всему дереву элементов, найти все экземпляры 'ViewModelControl' и выдать им реализацию сервиса резолва/создания View через внешнее свойство типа IViewService. Однако, это не самый быстрый вариант, особенно, для XAML с большим количеством элементов.
0
|
||||||||||||||||
| 29.10.2020, 00:47 | |
|
Ответы с готовыми решениями:
45
Обращение к элементу UI своего контрола-наследника из xaml другого класса Создание собственного контрола. Наследник textbox не отображает xaml код
|
|
Модератор
|
|||
| 29.10.2020, 20:53 | |||
|
Поэтому у меня большие подозрения, что вы просто плохо знаете инструменты WPF. Вам же не с чем будет сравнивать. В этом и беда корифеев о которых я писал выше. Они даже не понимают, что то, что они пишут значительно сложнее, чем если это делать предусмотренными для WPF средствами. kotelok, если вы убеждены делать как-то по своему - делайте. Кто вам может запретить. Я всего лишь пишу, что с очень большой вероятностью вы плохо изучили WPF. И советую сначала нормально его изучить. Потом вы хотя бы сможете объективно сравнить оба подхода.
1
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||
| 29.10.2020, 21:28 [ТС] | |||
|
P.S.: и я не убеждён, я просто ориентируюсь по фактической ситуации ... более того, сам себя я каждый раз пытаюсь убедить, что описываемые вами подходы правильные, что надо через них, что все крупные проекты так делают (наверное), и каждый раз в попытках реализовать что-нибудь простое, рефлекторно начинаю рефакторить код в менее перегруженный и в более дружественный к программисту, в результате чего каждый раз получаются различные варианты ViewModel-first.
0
|
|||
|
Модератор
|
||||
| 29.10.2020, 21:46 | ||||
|
Мне хватило 3-4 месяцев осилить и C# (о котором слышал, но ничего не знал), и WPF (о котором даже не знал). Как ни как основной язык WPF - это XAML. Это совершенной иной (по сравнению с C#) язык, вообще, лежащий "в другой" плоскости. Они позволяют получить Решение не изучая нового. Но Решения получаются более громоздкими и архитектурно сложными. То есть выбирать приходится между "не учить и сделать по старому, пусть и сложно" или "потратить время и силы на изучение нового и сделать потом проще и лучше". Добавлено через 7 минут Посмотрите на большинство Решений C# в Консоли и Формах. Сделаны так, как-будто ООП не существует, я уже не говорю о паттернах программирования. И все авторы такого кода, тоже убеждены, что делаю проще и лучше. И оценить объективно это может только тот, кто хорошо владеет ООП и умеет реализовывать паттерны. Так же и в вашем случае. Овладейте сначала в достаточной мере WPF и MVVM - тогда сможете судить объективно. Уже писал в начале темы. Такой абстрактный разговор выливается в бесполезный холивар. Надо рассматривать конкретные задачи. С одной стороны научитесь их реализовывать разными подходами. С другой набравшись опыта, сможете объективно оценивать эти подходы.
1
|
||||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 29.10.2020, 22:01 [ТС] | ||
|
P.S.: типичную задачу я уже описывал выше, в случае ViewModel-first она решается через единственный маленький кусочек кода внутри VM (остальное за кулисами делает фреймворк), в случае с View-first - возникает потребность придумывать сложные механизмы взаимной реакции View и VM на изменения состояний друг друга просто чтобы закрыть окно по факту успешнего сохранения данных во VM.
0
|
||
|
Модератор
|
|||
| 29.10.2020, 22:10 | |||
|
И что вы тогда собираетесь из пустого CB перетаскивать в VM ? Добавлено через 1 минуту И вам сразу написали, что это неверно. Что за задачу вы хотите решить таким инструментом - вы так и не написали.
0
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||
| 29.10.2020, 22:23 [ТС] | |||
|
Типичная задача создания/удаления nested-контрола (и VM для него) в процессе реакции на какое-то событие модели (или VM). И ещё раз - я решал эти задачи через View/XAML, но далее не справлялся с попытками довести эти решения до того же уровня простоты кода, что даёт подход VM-first.
0
|
|||
|
Модератор
|
||
| 29.10.2020, 22:31 | ||
|
Это же ООП !!! Здесь всегда куча типов, файлов, методов и т.п. Такая задача не то, что WPF - она самой концепции C# противоречит. На каждую фигню - надо создавать свой тип. На каждую операцию - свой метод. Файлов ДОЛЖНО быть много! Может поэтому вам и WPF сложно освоить. Дефолтные WPF элементы - это всего лишь костяк WPF. А для нормальной реализации WPF Решения к ним создаётся множество различных типов: конвертеры, AP-свойства, Behavior, Триггера, разнообразные контейнеры, статические классы с обработчиками, UserContol'ы, Custom Control'ы, различные прокси, шаблоны, стили, словари и т.д. и т.п. Не создавая всего этого, конечно, трудно будет только на дефолте красиво реализовать WPF Решение.
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||||||
| 30.10.2020, 00:12 [ТС] | |||||||||||
|
Элд Хасп
Это всё очевидно, да. И я тоже предпочитаю максимально разделять код на маленькие блоки, если вдруг один класс начинает выполнять хоть немного не свою работу. Однако, если для решения конкретной задачи есть возможность упростить код, выбрав какой-то иной подход, или же спрятав часть функционала в общие модули, то я предпочитаю ей пользоваться. Как минимум, с точки зрения упрощения обслуживания этого кода и, как следствие, снижения количества возможных ошибок. Добавлено через 15 минут Если не сложно, приведите вариант XAML-разметки под конкретный пример. В разметке есть кнопка. При нажатии на эту кнопку нужно: 1. Создать диалоговое окно, создать для него VM, передать ей параметр, связать VM и созданный View. 2. Показать окно модально, дождаться пока пользователь его закроет. 3. По результату закрытия окна сделать что-то с той VM из окна которой нажималась кнопка. При подходе VM-first в XAML будет:
Вероятно, именно в силу нехватки опыта и усидчивости, у меня не получилось свести этот код к тому же минимуму при работе от View.
0
|
|||||||||||
|
Модератор
|
|||||||||||||||||||
| 30.10.2020, 09:59 | |||||||||||||||||||
|
Мы обсуждаем тот или иной подход при реализации на "дефолте" или при использовании какого-то фрамеворка? Если первое, то все "внутренности фрамеворка" тоже являются частью реализации вашего подхода. И он получится, без вариантов, на много сложнее чем любой "дефолтный" вариант. Если же второе, то конечно использование средств фрамеворка сокращает код и здесь можно только обсуждать какой фрамеворк лучше подходит для каких типов задач. И "сокращает" далеко не всегда означает "улучшает". Задача ли это? Откуда взялись эти условия? Конечно, это не Задача. Её можно назвать Локальной задачей поиска решения для уже в большей части созданного окружения. Задача более глобальна. И эти условия появились исходя из вашего понимания как нужно реализовать саму Задачу. Как вы построили архитектуру приложения. Вы это делали исходя из своих знаний и вполне вероятно выбрали неверную архитектуру. Подогнанную не под оптимальное использование WPF, а под имеющиеся у вас знания. И в такой неверной архитектуре у вас возникает потребность в реализации определённых действий. Но может в оптимальной архитектуре в них не возникла бы потребность? Или потребовались другие? С вашей точки зрения она выполняет первый пункт условий. Но это не так. Если мы говорим о НЕЗАВИСИМЫХ слоях MVVM, это вызов команды VM. Будет ли по ней открыто окно или нет автор View, в принципе, знать не может. А верно ли это? А если он считает, что лучше в GUI дизайне для редактирования параметра надо не открывать новое окно, а перейти в текущем на другую страницу, или в текущем Окне создать регион для редактирования? Что ему делать? Ему придётся обращаться к автору VM с требованием изменить РЕАЛИЗАЦИЮ команды! Тем самым в таком подходе, вы делаете VM частью View и создавать их независимо друг от друга просто невозможно. То есть , фактически вы выкидываете VM из MVVM. Да, у вас есть некий тип который так НАЗЫВАЕТСЯ, но по функционалу он ни как не ViewModel. Это либо часть View, либо какая-то смесь с Контролером/Презентером. SelectedId.А что это за свойство, и для чего оно в VM? Только для того чтобы быть переданным в команду? В таком случае у вас опять искусственно внесена часть функционала View в ViewModel. И в такой смеси часть реализующая это свойство, привязка к нему это тоже часть реализации вашей локальной задачи. С точки зрения WPF+MVVM, что должна делать эта команда? Открыть диалоговое Окно для полученного параметра. Условно это будет так:
Нет. И следовательно эта команда не должна быть в VM. Как эта VM связана с Моделью? Условно можно в команду выше добавить реализацию метода ShowAndWait:
То есть мы опять возвращаемся к искусственно внедрённым зависимостям в изначально независимые слои приложения. Сначала вы создали неправильную архитектуру приложения, внесли в неё паразитные связи, а потом вопрос как правильно решить в этой куче непонятно чего?
1
|
|||||||||||||||||||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 30.10.2020, 10:52 [ТС] | |
|
Элд Хасп
Спасибо, если время будет, попробую на выходных ещё раз с нуля из типового CB-решения получить MVVM-вариант. Хотя, пока что закрадываются подозрения, что конкретно под мои условия MVVM попросту не нужен, т.к. на проекте (несмотря на общий огромный размер) точно не будет разделения программистов слои и логика V+VM всегда будет реализовыаться одним человеком в рамках конкретной UI-задачи, а значит, пусть даже ценой более жёсткой связанности/зависимости V+VM, вполне можно отказаться от сложностей MVVM ради упрощения кода и работы программистов.
0
|
|
|
Модератор
|
|||
| 30.10.2020, 11:20 | |||
|
Другой вопрос как оценивать "сложность" и "упрощение". Оценка субъективна и очень зависима от знаний и опыта субъекта. Если вам и вашей компании проще так как вы делаете и ни о каких перспективах дальнейшего роста речь не идёт, то, конечно, оставьте всё как есть. Добавлено через 3 минуты Сразу говорю, ничего толкового не выйдет. Раз в WPF Решении активно используется CB, то с вероятностью 99,99% у Решения неверная АРХИТЕКТУРА. И надо не ПЕРЕДЕЛЫВАТЬ приложение, а создавать его С НУЛЯ, начиная с проектирования его архитектуры.
1
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 30.10.2020, 11:30 [ТС] | ||
|
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 30.10.2020, 11:37 [ТС] | ||
|
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 30.10.2020, 12:31 [ТС] | ||
|
Т.е. слой Model на стороне фронта, по-большей части, будет минимальной прослойкой между VM и API. Вероятно, там так же будет какое-то локальное кэширование.
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||||||
| 30.10.2020, 19:07 [ТС] | ||||||
|
Не, не получается придумать решение.
В XAML есть кнопка:
1. Показать другой View модально относительно текущего (в котором кнопка). Как это сделать: 1. Не перенося логику инициации показа диалога во VM (пусть даже и косвенно через абстракцию). 2. Не используя CB. Добавлено через 30 минут Почему-то даже нагуглить это не получается - большая часть примеров через CB, немного через VM, и всё. Нашёл какой-то вариант через встраивание C#-кода напрямую в XAML, однако, выглядит это совсем уж жутко, да и по-сути это всё тот же CB.
0
|
||||||
|
Модератор
|
|
| 30.10.2020, 19:51 | |
Сообщение было отмечено kotelok как решение
Решение
kotelok, есть два основных способа решения:
Использование обработчика Click. Можно его задать в CB самого окна, или в его XAML. Но так же есть варианты: - создать статический класс обработчиков - ссылку на пример я давал выше; - сделать статический обработчик в CB диалогового окна. Вызов станет подобен статическому методу MessageBox.Show(...); - создать AP-свойство или Behavior. Второй способ - использование команд: - изначально MS предполагала использование команд только внутри View. Для этого были созданы всплывающие команды RoutedCommand. При всплытии они ловятся и передаются в обработчики. Обработчики присоединяются подобно как выше указанно для Click. Я содавал специальное AP свойства для биндинга RoutedCommand к обычным командам Освоение Attached Properties: Списочное свойство - задание команды с реализацией. Создаёте экземпляр команды в ресурсах и ссылаетесь на него. Если подобных команд несколько, то удобнее сделать один тип с несколькими свойствами командами. Как видите вариантов реализации множество - полтора-два десятка. Какой конкретно выбрать зависит от деталей задачи. Для вашей, чтобы показать пример, мне нужны уточнения: - Какой из вариантов вам больше импонирует? - Что значит "относительно текущего (в котором кнопка)"? Какие "знания" должны быть у Диалогового Окна о Родительском? - Есть ли какая-то передача данных между ними?
1
|
|
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 30.10.2020, 20:15 [ТС] | |
|
Элд Хасп
Сценарии у меня стандартыне для десктопа: 1. Список айтемов, даблклик в айтем, модальное диалоговое окно редактирования айтема, которое на вход получает ID кликнутой записи, вытягивает её полные данные с сервера, кнопки ок/отмена, и по факту закрытия вызывающая форма получает информацию о результате выполнения (обновлена запись или нет). 2. Кнопка, по которой отображается НЕ модальное окно и ссылка на него запоминается. При повторном клике в кнопку, если окно всё ещё живо, оно просто активируется/восстанавливается, если же пользователь уже закрыл его, то создаётся и отображается новое. 3. Кнопка, по которой отображается НЕ модальное окно с выдачей ему ID записи. При повторном клике в кнопку, если уже есть живое окно с таким ID записи, то оно просто активируется, если нет, то создаётся новое (т.е. одновременно может быть открыто множество таких немодальных окон). Но примеры пока не нужно, попробую самостоятельно почитать про озвученные варианты решения.
0
|
|
| 30.10.2020, 20:15 | |
|
Ошибки на этапе создания проекта MySQL виснет при установке, на этапе создания my.ini На каком этапе создания сайта можно приступать к оптимизации DBGrid: как отключить отображение информации на этапе создания? Зависает на этапе создания окна. До списков даже не доходит Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
|