|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||
WPF Как внедрить модель во viewModel?26.12.2024, 11:19. Показов 25466. Ответов 295
День добрый. Есть у меня метод в проекте, который вызывается из конструктора. Метод по типу "Получить все из бд и вывести на экран".
Смущает меня то, как именно я это делаю. Когда происходит загрузка, UI блокируется. Да и в целом все очень медленно и дальше будет только хуже с добавлением данных. Теперь код.
0
|
||||||
| 26.12.2024, 11:19 | |
|
Ответы с готовыми решениями:
295
Как зарегистрировать ViewModel через Autofac, создав между ViewModel и нужным View DataContext связь?
|
|
Модератор
|
|||||||||||
| 31.12.2024, 14:04 | |||||||||||
|
Vissmuy, несколько нюансов.
Startup="OnStartup"> - заменено переопределение OnStartup на вызов обработчика события. Причина: Ресурсы приложения и запуск основного окна из Code-Behind App [WPF, Элд Хасп]Подсоединение второго обработчика Startup в конструкторе
await и потом синхронный вызов переходит к следующему обработчику. После завершения await происходит возврат к синхронному исполнению дальнейшего кода, но к этому времени все другие синхронные обработчики уже будут выполнены.Синхронизация привязки к коллекции:
0
|
|||||||||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||||||||
| 01.01.2025, 11:09 [ТС] | ||||||||||||
|
А почему для Get и Set словарь хранит значение типа object, а в командах прямо указано RelayCommand?ViewModelBase.GetSet
0
|
||||||||||||
|
Модератор
|
|||
| 01.01.2025, 13:16 | |||
|
Vissmuy, к клаcсам из Step1 относитесь просто как библиотеке. Не важно как они устроены. Вам нужно знать только как их использовать.
Любое значение можно хранить в object. При этом будут потери (времени) на упаковку/распаковку или приведение. Чтобы не было этих потерь, придётся делать на каждый тип свой собственный словарь. Надо будет сначала искать нужный словарь типа и только потом выбирать нужное значение из него. В целом это вряд ли будет более оптимальным, но точно будет гораздо более сложным по коду. При создании команды с параметром можно получить экземпляры RelayCommand<T>, но они производные от базового RelayCommand и ничем кроме конструктора от него не отличаются. Поэтому тип параметра имеет значение только при создании команды. А для её использования это безразлично. И хранить тип параметра поэтому тоже не нужно. Достаточно знать что это RelayCommand. Добавлено через 6 минут В ViewModelBase есть статическое свойство IsInDesignModeStatic. Если оно true значит приложение находится в Режиме Разработки.Это можно использовать для изменения логики в зависимости от режима. В данном случае это не нужно, поскольку SQLite автоматически создаётся через Code First. Но в других случаях может быть очень полезным, так как не любой тип источника можно заставить корректно и одинаково работать в различных режимах. Добавлено через 1 минуту Есть свойство Dispatcher.Его при необходимости можно использовать для синхронизации с View, но лучше создавать такой код где это не понадбится.
0
|
|||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||||||||||||||||
| 02.01.2025, 06:17 [ТС] | ||||||||||||||||||||
|
Элд Хасп, хочу уточнить - нормально ли то, что
MainViewModel взяла на себя функции из других ViewModels? Например, команда по добавлению сущности была в AddBirdViewModel, теперь же класс по сути лишний, так как он пустой. Разве не должно быть разделения логики, дабы не городить все в одном классе? Bird и, к примеру, Set, то есть набор сущностей Bird. Связь один ко многим.У меня есть generic интерфейс IRepository, который, как я понял, имеет общую логику репозиториев.В классе, который его наследует (В учебном проекте это DbBirdsRepository) есть методы для операций с бд.Получается, что мне нужно будет два таких репозитория, один для Bird, как сейчас и второй для Set, так ведь?
Можете пожалуйста рассказать, что за @new? Погуглив узнал, что модификатор new скрывает реализацию базового класса и можно как бы переопределить класс без модификаторов virtual и override. Что-то типа того. Сильно не всматривался. Но про @new как то и не нашел.
Когда подробней смотрел в класс BaseInpc, в методе Set стало не понятно, почему так. Вот строка - ArgumentException.ThrowIfNullOrWhiteSpace(propertyName);. Но у нас же propertyName имеет значение по умолчанию null. Я так понял, что это если Set вызывается не из свойства. Во ViewModelBase.GetSet тоже самое.Но разве может быть необходимость вызывать этот метод не из свойства?
Элд Хасп, и да, если или когда начнете снова вносить изменения в проект, не забудьте пожалуйста запулить проект, были некоторые корректировки. Добавлено через 15 минут Также не нашел класс, в котором происходит регистрация объектов в DI-контейнер. В нем больше нет необходимости? Добавлено через 8 минут App? Проследил метод до репозитория, там увидел строку - public async Task LoadAsync() => await Task.Run(birds.Load);birds тут - это DbSet. То есть происходит загрузка в DbSet данных, так выходит?Вот описание метода Load.
0
|
||||||||||||||||||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||
| 02.01.2025, 06:25 [ТС] | ||||||
|
Также в AddBirdView есть ComboBox с привязкой к коллекции. Но последние две строки работают как-то странно. Они просто скрывают элементы.
Эффект, если удалить две последние строки.
0
|
||||||
|
Модератор
|
||||||||||
| 02.01.2025, 11:12 | ||||||||||
|
Нормально. команда по добавлению сущности может потребоваться в любой дочерней VM, поэтому для уменьшения дублирования кода её можно перенести в основную VM. Если бы таких команд и других членов было бы очень много, то для упрощения привязок можно было предоставлять их через прокси свойства и в дочерней VM. Например, как это сделано со свойством BirdNameGroups.Но это потребует внедрения механизма отслеживания изменений связанных сущностей. Birds.Add - Id будет задаваться механизмами БД.А при инициализации БД в методе её конфигурирования OnModelCreating метод HasData записывает сущности "как есть". Поэтому в данном случае нужно "руками" задать Id.
Например, в методе ViewModelBase.SetSet, вызывается метод BaseInpc.Set.Но эти методы бессмысленно вызывать, если не передавать имени свойства. Проверить точно есть ли такое свойство можно, но это сложно. А вот проверить есть ли там хоть какое-то имя - можно. ArgumentException.ThrowIfNullOrWhiteSpace(propertyName) и делает такую проверку.На данном этапе вам нужно понять как создаются связи между слоями, объектами. Когда поймёте, как это делается "руками", то при необходимости сможете внедрить DI-контейнеры. DI контейнеры требуют начальной регистрации типов. Я уже вам показал какие ошибки это может вызвать, если это делать в Code Behind. Для удобства Конструирования XAML нужна регистрация слоёв в XAML. И это сложно сочетать с DI контейнерами. Можно, но сложно. В данном случае у вас и так хватает сложностей в которых надо разобраться, поэтому добавлять сюда "разборки" с DI контейнерами посчитал преждевременным. Связывание локального кеша с View происходит сразу при запуске приложения. Но локальный кеш пуст. Надо его загрузить. Загрузка может занять длительное время. Поэтому её надо отделить от связывания и запустить асинхронно. Это просто для примера, так как не понял для чего он здесь. Надо заменить на требуемую для вас логику.
0
|
||||||||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
|||||||
| 02.01.2025, 12:58 [ТС] | |||||||
Singleton, но реализованный через словарь. Когда я переключаю представление, то сначала срабатывает метод Get, а потом уже в Set в старое значение по ссылке присваивается новое.Добавлено через 15 минут А с какой целью в этой команде производится клонирование? И немного не пойму, что значит индикация выполнения метода.
0
|
|||||||
|
Модератор
|
||||||
| 02.01.2025, 13:39 | ||||||
|
Добавлено через 22 минуты Если реализацию делать безопасной, то требуется использование иммутабельных DTO. Второй нюанс - это "когда должны отобразиться изменения в View?" View - это представление Модели. Поэтому будет некорректным, если мы изменим свойства сущности представляемой в View до того как эти изменения будут зафиксированы в Модели. Поэтому создаём дубль, вносим в него изменения, фиксируем изменения в Модели и только после фиксации новая сущность, с уже новыми данными, поступит в View для представления. В данной реализации в этом нет необходимости, поскольку SQLite локальна и метод выполняется за миллисекунды. По сути здесь даже нет необходимости в асинхронном методе. Синхронного было бы вполне достаточно. Но возможно у вас есть какая-то другая рабочая реализация, в которой это действительно долго выполняется. Добавлено через 3 минуты Добавлено через 2 минуты О работе свойства Current? Это не Синглтон, но DI заменён на явное создание дочерних VM.
0
|
||||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||||
| 02.01.2025, 14:13 [ТС] | ||||||||
ViewModelBase. Сначала же идет проверка, есть ли в нем нужное свойство.
А есть еще один проект. Этот учебный как раз таки слизан с того, там по сути все те же проблемы. Потом как этот учебный изучу, будет интересно попробовать переделать его. Так вот в нем 4к объектов в бд. На хостинге там секунд 6 грузится.
0
|
||||||||
|
Модератор
|
|||
| 02.01.2025, 14:21 | |||
|
Если нет, то возвращается значение по умолчанию для типа. Изменить значение в словаре можно только методом Set. Но это не имеет отношения к Singleton. Напротив, пред усматривается хранение разных экземпляров. Здесь может иметь значение не сколько запись, а удалённая БД это или локальная, есть ли многопользовательский режим. Если удалённая и/ил многопользовательская, то как работает с ней сервис и т.п. А для локальной однопользовательской БД даже для 3млн. записей выполнение будет практически мгновенным.
0
|
|||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||
| 02.01.2025, 14:26 [ТС] | ||
|
0
|
||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
|
| 02.01.2025, 14:27 [ТС] | |
|
Забыл вложение удалить, там испорченный коммент из pull request.
0
|
|
|
Модератор
|
||||
| 02.01.2025, 15:15 | ||||
|
У меня вроде всё ок. Добавлено через 5 минут Проверил сейчас свой Fork - почему-то он не совпадает с моим локальным Репозиторием. Пытаюсь разобраться. Добавлено через 2 минуты А.... Это я косяканул. Fork обновил, а локальный реп нет. Добавлено через 24 минуты Можно скопировать из предыдущих комитов. Добавлено через 26 секунд Отправил исправление конфликта слияния и коммента.
0
|
||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
|||||||||||||||||
| 05.01.2025, 09:23 [ТС] | |||||||||||||||||
Bird задаются через конструктор. Почему теперь так? В чем отличие от предыдущего варианта?Что означают эти строки в BirdsWPF.csproj?
Find находит сущность в другом единоразовом контексте? Или контексты делятся между собой данными, хранящимися в DbSet?
0
|
|||||||||||||||||
|
Модератор
|
|||||
| 05.01.2025, 11:26 | |||||
|
Иммутабельный DTO - это более "чистая" реализация MV*.Это Студия так настраивает проект. Можно делать это и "руками", но это совершенно отдельная область знаний не имеющая отношения к Шарпу. Обращаюсь к ней только, если возникают какие-то шибко нестандартные проблемы при сборке, переносе проектов. Создаются для упрощения XAML. В данном случае, надо создать экземпляр иммутабельного типа Bird. У него нет конструктора по умолчанию. Создать его можно или при помощи ObjectDataProvider (Провайдеры данных. ObjectDataProvider | METANIT.COM), либо через свое "самописное" расширение разметки. В данном случае, в новом контексте происходит запрос на удаление. Если запрос удачно выполнился (не было исключения), то с помощью Find ищется такая же сущность в постоянном контексте. Если она там есть, то происходит её перезагрузка. А так как на этот момент в БД она уже удалена, то перезагрузка приводит и к удалению сущности из постоянного контекста.
0
|
|||||
|
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
|
||||||
| 08.01.2025, 12:12 [ТС] | ||||||
|
Есть такая вот проблема. Когда я нажимаю на кнопку "Удалить", то сначала выводится значение по умолчанию для DateOnly, но после переключения вида значение становится нормальным. Как сделать, чтобы значение сразу было нужным?
Команда
Сразу после нажатия кнопки После переключения вида.
0
|
||||||
|
Модератор
|
||
| 08.01.2025, 14:19 | ||
|
Используется механизм PropertyDescriptor. В этом варианте для примера было уведомление только о свойстве IsActive. Сейчас скинул вариант с уведомлением обо всех свойствах. На данный момент я показал вам три варианта: 1) С внедрением INPC в мутабельную сущность для EF; 2) С заменой иммутабельной сущности в локальном кеше Контекста; 3) С вызовом обновления привязок к сущности без внедрения INPC. Все эти реализацию относятся к "дружественным". То есть когда хоть и нет прямой связи Контекста с другими слоями, но все же требуется соблюдать некие правила по работе с ним, и Репозиторий должен так же выполнять некие дополнительные неоговоренные требования для правильной работы остальных слоёв. Есть ещё "безопасные" реализации. В них потребуется несколько больше кода, так как сущности используемые Контекстом ни при каких обстоятельствах не выходят из Репозитория. Даже если используется один и тот же тип, то происходит его копирование или отсоединение от контекста перед передачей. В такой реализации потребуется уже "ручное" создание локального кеша и, скорее всего, события в Репозитории уведомляющие об его изменении. Не смотря на более сложную реализацию, такие "безопасные" Репозитории более предпочтительны и считаются более качественным исполнением. В коллективной работе практически всегда используются именно "безопасные" реализации (не только Репозиториев).
0
|
||
|
Модератор
|
|
| 08.01.2025, 22:25 | |
|
0
|
|
| 08.01.2025, 22:25 | |
|
Mvvm ViewModel в ViewModel Как внедрить БД в exe на VB 6.0 Как внедрить функцию как с внедрить свой код
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
|
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет:
1. Использовать системное время и дату,
2. Есть возможность вводить время и дату вручную.
3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
|
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber.
Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
|
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео:
https:/ / vkvideo. ru/ video-240781534_456239017
YouTube:
eY5-5PyI9NM
Текстовая версия
|
|
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать
Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
|
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства.
Родственных связей существует 8 ступеней, такие как:
p - отец
P - мать
q - муж
Q - жена
b - брат
B - сестра
s - сын
S - дочь
|
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире.
Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|