Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
WPF

Как внедрить модель во viewModel?

26.12.2024, 11:19. Показов 25452. Ответов 295
Метки mvvm (Все метки)

Студворк — интернет-сервис помощи студентам
День добрый. Есть у меня метод в проекте, который вызывается из конструктора. Метод по типу "Получить все из бд и вывести на экран".

Смущает меня то, как именно я это делаю. Когда происходит загрузка, UI блокируется. Да и в целом все очень медленно и дальше будет только хуже с добавлением данных.

Теперь код.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class BirdsViewModel : ObservableObject
{
    // [B]Конструктор[/B]
    public BirdsViewModel(IBirdRepository birdRepository, Func<BirdEntity, BirdViewModel> birdView) // [B]Прошу обратить 
//внимание на делегат. Его, думаю, и нужно заменять.[/B]
 
    {
        Birds = [];
        _birdView = birdView;
        _birdRepository = birdRepository;
        LoadBirds();
    }
 
// [B]Проблемный метод[/B]
private async void LoadBirds()
{
    var birds = await _birdRepository.GetAllAsync(); // [B]Получение данных из БД[/B]
    switch (Name)
    {
        default:
            foreach (var bird in birds)
                Birds.Add(_birdView(bird)); // [B]С помощью делегата я во ViewModel передаю Entity, 
//с которой та и работает. Есть ли другие методы подобной реализации, чтобы у каждой ViewModel был свой Entity?[/B]
            break;
    }
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.12.2024, 11:19
Ответы с готовыми решениями:

Как из ViewModel UserControl'a изменить свойство в ViewModel главного окна?
Недавно начал попытки создавать приложение WPF с применением MVVM, и у меня возник вопрос, который не даёт мне продвигаться в разработке...

Как зарегистрировать ViewModel через Autofac, создав между ViewModel и нужным View DataContext связь?
Доброго времени суток. Есть желание при регистрации ViewModel'и сразу же &quot;подключиться&quot; к DataContext'у у нужной View, как например: ...

WPF получить доступ из одной viewmodel к другой viewmodel
Собственно есть у меня две viewmodel, mainviewmodel и settingsviewmodel, в mainviewmodel есть вот такая штука private Visibility...

295
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 14:36  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
И проект MVVM выглядит примерно вот так
Библиотеки классов вот прям обязательное правило?
0
 Аватар для Andrey-MSK
3390 / 2276 / 388
Регистрация: 14.08.2018
Сообщений: 7,696
Записей в блоге: 4
28.12.2024, 14:42
Цитата Сообщение от Vissmuy Посмотреть сообщение
Библиотеки классов вот прям обязательное правило?
Разделение на разные проекты нужно для понимания что и за что отвечает, и не проникает ли логика нижестоящего слоя в вышестоящий.

Добавлено через 3 минуты
Vissmuy, Иерархия проекта MVVM
1. Model - сам по себе, самый нижний слой, не знает вообще ни о чём.
2. ViewModel - знает про Model и Services.
3. Services - различные сервисы, работают сами по себе и не знают ни о ком.
4. View - знает про ViewModel и Services.
5. Application (часто совмещён с View) - знает всё про всех, соединяет всё в одну кучу с помощью DI.
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 14:49  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Иерархия проекта MVVM
У меня также, только вместо разных проектов один, и все в папках. Наверное, если проект большой, то лучше как у вас делать.
0
 Аватар для Andrey-MSK
3390 / 2276 / 388
Регистрация: 14.08.2018
Сообщений: 7,696
Записей в блоге: 4
28.12.2024, 14:52
Цитата Сообщение от Vissmuy Посмотреть сообщение
Наверное, если проект большой, то лучше как у вас делать.
Размер проекта значения не имеет.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
28.12.2024, 14:55
Vissmuy, Andrey-MSK прав.
Смысл Репозитория в том чтобы его можно было открыть в Студии, проверит ошибки, отдебажить и т.д.
Нужно целиком Решение, а не отдельный проект.
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 15:05  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Нужно целиком Решение, а не отдельный проект.
Можно немного подробней, я сегодня первый раз на GitHub зашел.

Добавлено через 14 секунд
Если не затруднит, конечно.

Добавлено через 3 минуты
Я воспользовался приложением GitHub Desktop. Зашел на свой ноут, скачал Zip-архив этого проекта, распаковал и открыл решение, запустил, все так, как и должно быть.

Как мне стоит сделать, чтобы было проще?
0
 Аватар для Andrey-MSK
3390 / 2276 / 388
Регистрация: 14.08.2018
Сообщений: 7,696
Записей в блоге: 4
28.12.2024, 15:05
Цитата Сообщение от Vissmuy Посмотреть сообщение
Можно немного подробней
Открыли решение в студии, далее меню -> Git -> Create Git Repository
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 15:48  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Открыли решение в студии, далее меню -> Git -> Create Git Repository
Я пробовал клонировать, дабы новый не создавать, он мне просто папку создает и все пустую.

Добавлено через 26 минут
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Открыли решение в студии, далее меню -> Git -> Create Git Repository
https://github.com/Londongrad/BirdsWPF Вот создал через студию, ничего не изменилось по структуре файлов

Добавлено через 46 секунд
Цитата Сообщение от Vissmuy Посмотреть сообщение
ничего не изменилось
Ну окей, чутка погорячился, изменения вижу

Добавлено через 14 минут
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Тогда тип DateOnly должен быть.
Разобрался, но есть ли возможность изменить формат даты на день/месяц/год, при этом сохранив тип переменной (не переводя в string)?
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
28.12.2024, 16:04
Vissmuy,
XML
1
Text="{Binding MyDate, StringFormat=dd/mm/yyyy}"
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 16:16  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
Text="{Binding MyDate, StringFormat=dd/mm/yyyy}"
А если не в xaml?

К примеру, вот строка. Формат даты = 12/28/2024
C#
1
private DateOnly _arrival = DateOnly.FromDateTime(DateTime.Now);
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
28.12.2024, 16:28
Vissmuy, какой смысл менять формат представления даты в DateOnly? Правильно - никакого!
Формат меняют при показе/выводе куда-то. Хранение даты должно быть в оригинальном виде.
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 16:48  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
Формат меняют при показе/выводе куда-то.
Ну так это поле, на которое ссылается свойство. Эта дата выводится.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
28.12.2024, 16:58
Vissmuy, еще раз: DateOnly/DateTime - это типы, которые живут в системе. Изменить их содержимое ты не сможешь. А выводят их куда-либо в необходимом виде - применяя форматирование. И когда ты смотришь на эту дату в каком-нибудь TextBlock'е в нужном тебе представлении, то становится абсолютно фиолетово то, как и в чем она хранится где-то в недрах кода.
Изменять свойство на string для этого не нужно. Так или иначе, можно сказать, что все данные которые выводятся в окно - представляют из себя строковые типы, в которые их конвертирует XAML автоматически.
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
28.12.2024, 17:13  [ТС]
Цитата Сообщение от wizard41 Посмотреть сообщение
еще раз
То есть в коде пусть будет какой угодно формат, а в xaml я сделаю stringFormat, так?
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
28.12.2024, 17:17
Цитата Сообщение от Vissmuy Посмотреть сообщение
То есть в коде пусть будет какой угодно формат, а в xaml я сделаю stringFormat, так?
Бинго!
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3461 / 2782 / 575
Регистрация: 04.09.2018
Сообщений: 8,745
Записей в блоге: 3
28.12.2024, 17:31
Свойство одно:
C#
1
2
3
4
5
6
    private DateTime date;
    public DateTime Date
    {
        get => date;
        set => Set(ref date, value);
    }
а вывести можно как угодно:
XML
1
2
3
4
5
6
    <StackPanel Margin="20">
        <TextBlock Text="{Binding Date, StringFormat=dd.MM.yyyy}"/>
        <TextBlock Text="{Binding Date, StringFormat='{}{0:dd MMMM, yyyy}'}"/>
        <TextBlock Text="{Binding Date, StringFormat=dd/MM/yyyy}"/>
        <TextBlock Text="{Binding Date, StringFormat=yy.MM ddddd}"/>
    </StackPanel>
Изображения
 
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
29.12.2024, 00:49
Цитата Сообщение от Vissmuy Посмотреть сообщение
Разобрался, но есть ли возможность изменить формат даты на день/месяц/год, при этом сохранив тип переменной (не переводя в string)?
Конечно.
Можно задать культуру (в привязке или элементе). Можно задать кастомный стринг формат в привязке.

Добавлено через 2 минуты
Не понял вопроса.
Для string - нет. Это же просто строка. Как строка она и выводится.
Можно изменять только при создании строки.

Добавлено через 4 часа 18 минут
Цитата Сообщение от Vissmuy
Text="{Binding Departure, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type vm:BirdsViewModel}}}"
Не пойму логику работы этого поля.
Судя по коду в нём должно время старта приложения (точнее вызова конструктора BirdsViewModel).
Но поле редактируемое. Там можно изменить дату. После нажатия кнопки эта дата записывается в BirdDeparture.
И сбрасывается флаг bird.IsAlive.
Вроде верно?

Не пойму от чего зависит видимость кнопки.
Есть привязка Visibility="{Binding Visibility}", но где свойство к которому привязка происходит?

Добавлено через 2 минуты
Если судить по этому сообщению Под кнопкой есть поле ввода, при нажатии данные из поля устанавливаются в свойство и кнопка исчезает. В ее функционале более нужды нет, то видимость кнопки зависит от флага IsAlive. Если false - то кнопка сворачивается.

Добавлено через 7 минут
TextBox тоже должен стать невидимы.
Наверное и TextBlock - "чёрточка" тоже тогда не нужен.

Добавлено через 1 час 10 минут
Ещё есть два TextBlock перед этой кнопкой и Departure. Один с чёрточкой, второй непонятно с чем.
Как их видимость должна меняться?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
29.12.2024, 00:50
Добавлено через 1 час 8 минут
Vissmuy, я отправил вам "Pull request" - посмотрите. Изменения в ветке "eldhasp".
0
 Аватар для 2033
4 / 4 / 1
Регистрация: 26.12.2024
Сообщений: 225
29.12.2024, 06:28  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
я отправил вам "Pull request" - посмотрите.
Посмотрел, спасибо. Сколько бы видео я не посмотрел на YouTube на русском и английском - никогда не встречал ничего такого. Я не туда смотрел? Просто мне там вообще все непонятно.

К примеру вот это я уже тут видел в свойствах с ссылкой. Где смотреть про все это?

C#
1
2
3
4
5
6
7
8
9
10
11
12
protected void Set<T>(ref T propertyFiled, T newValue, [CallerMemberName] string? propertyName = null)
{
    ArgumentException.ThrowIfNullOrWhiteSpace(propertyName);
    if (!object.Equals(propertyFiled, newValue))
    {
        T oldValue = propertyFiled;
        propertyFiled = newValue;
        RaisePropertyChanged(propertyName);
 
        OnPropertyChanged(propertyName, oldValue, newValue);
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private RelayCommand<BirdEntity>? _deleteBirdCommand;
public RelayCommand<BirdEntity> DeleteBirdCommand => _deleteBirdCommand ??= new RelayCommand<BirdEntity>
(
    async bird =>
    {
        bird.Departure = Departure;
        bird.IsAlive = false;
        DeleteBirdCommand.RaiseCanExecuteChanged(); // Обновление команды
 
        await Task.Delay(2000); // Имитация долго выполнения
    },
    bird => bird.IsAlive
);
И про все остальное.


И разве тут может быть исключение? Разве ServiceProvider не делает тоже самое, что в блоке Catch? Или это на случай, если в DI-контейнер не занести BirdsViewModel?

У меня то BirdsViewModel в оригинальном коде в конструктор принимает репозиторий.
C#
1
2
3
4
5
6
7
8
try
{
    _currentView = App.ServiceProvider!.GetRequiredService<BirdsViewModel>();
}
catch (Exception)
{
    _currentView = new BirdsViewModel();
}
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
29.12.2024, 11:26
Цитата Сообщение от Vissmuy Посмотреть сообщение
Сколько бы видео я не посмотрел на YouTube на русском и английском - никогда не встречал ничего такого. Я не туда смотрел? Просто мне там вообще все непонятно.

К сожалению, вот такие вот все эти обучалки.
При этом если поинтересуетесь у более-менее уже знакомого с ООП и WPF (например у wizard41 или Andrey-MSK), для него ничего удивительно и непонятного в этом коде не будет.
По сути стандартные реализации для WPF.
Простые реализации для тем на форуме

Цитата Сообщение от Vissmuy Посмотреть сообщение
К примеру вот это я уже тут видел в свойствах с ссылкой. Где смотреть про все это?
Такая или подобная реализация метода присвоения значения свойству, есть почти в каждом пакете для MVVM. Но вот объяснений.... я затрудняюсь сказать есть они где-то или нет.

Вопрос про команду - не понял.
А что с ней непонятного?

Цитата Сообщение от Vissmuy Посмотреть сообщение
И разве тут может быть исключение? Разве ServiceProvider не делает тоже самое, что в блоке Catch?
Для того чтобы ServiceProvider корректно работал, он должен быть сначала инициализирован. Инициализация сервиса у вас производится в Code Behind App в обрабатчике OnStartup.
Но в Дизайнере (в режиме разработки) Code Behind не обрабатывается. Поэтому сервис не инициализирован, в Дизайнере выкидывается исключение. Можно конечно проигнорировать это, но лично мне не нравятся такие предупреждения Дизайнера, иногда из-за них он может даже отвалиться и приходится его перезапускать.

Вообще, почти для всех XAML платформ есть два режима "Режим Дизайнера (или Разработки)" и "Режим Исполнения (или Рантайм)". И желательно делать такую разработку в которой нормально и правильно работают оба режима.
Обратите внимание как сейчас в Дизайнере отображаются элементы. Видно их заполнение, можно переключать представления и т.д. Без обеспечения корректной работы всех типов в Режиме Дизайнера так не выйдет сделать.

Добавлено через 22 минуты
Я пока не спускался сильно глубоко. Просто не знаю насколько вам это нужно.
Если делать правильно MVVM, то нужно изолировать Модель.
В идеале у вас должен быть отдельный проект с Моделью в котором инкапсулирован, в частности, Репозиторий.
Тип BirdEntity это сущность уровня репозитория. Из Модели должен выходить не он,, а немутабельная DTO-шка.

Даже если упрощать Решение, так как по сути у вас только представление БД и нет другой Бизнес Логики, то всё равно функция изменения BirdEntity - это функция Репозитория. Все изменения свойств BirdEntity должны происходить через замену экземпляра.

Например, метод "Delete" должен выглядеть примерно так (это не готовый код - пишу "на вскидку"):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        public RelayCommand<BirdEntity> DeleteBirdCommand => _deleteBirdCommand ??= new RelayCommand<BirdEntity>
        (
            async bird =>
            {
                BirdEntity @new = null!;
                await Task.Run(() =>
                {
                    using var context = new Context();
                    @new = context.Birds.Find(bird.Id);
                    @new.Departure = Departure;
                    @new.IsAlive = false;
 
                    context.SaveChangeds();
                });
 
                int index = Birds.TakeWhile(b => b != bird).Count()-1;
                Birds[index] = @new;
            },
            bird => bird.IsAlive
        );
Примите мои изменения и добавьте в Решение БД Sqlite - эта БД переносится с Решением, поэтому проще для учебных коллективных разработок.
На таком примере я уже покажу как правильно работать с БД.

Добавлено через 8 минут
Здесь ещё важный момент определить когда происходит сохранение изменений. В современных приложения принято, что изменения сохраняются стразу, но здесь могут ограничения, если само сохранение очень долгое. Не замораживать же GUI на это время. Можно применять асинхронность, но многие источники по сути однопоточны и асинхронность у них формальна. Фактически они просто ставят задачи в очередь и выполняют их в одном потоке. SQLite например работает на блокировке файла БД. И пока одна транзакция не завершена, другая будет висеть в ожидании. "Взрослые" БД уже работаю на блокировке записей. И разные записи можно менять независимо.

Соответственно вопрос. Насколько глубоко вам нужно всем этим заморочиться, насколько критичны для вас эти моменты?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.12.2024, 11:26

Mvvm ViewModel в ViewModel
Есть одно окошко там много вкладок, в каждой вкладке есть подвкладки и там много разных таблиц и кнопок. ViewModel будет просто огромной,...

Как внедрить БД в exe на VB 6.0
Hi! Есть база на Access 7.0 и проект на VB 6.0. Можно ли как-нибудь всунуть .mdb файл в exe-шник, чтобы никто не мог его открыть и...

Как внедрить функцию
Здравствуйте, есть программа которая считает в edit сколько открывающихся скобок и закрывающихся. мой код выглядит так: procedure...

как с внедрить свой код
Всем привет! Не подскажите как можно создать свою папку в вордпресссом и внедрить свой код. Сейчас есть сайт на вордпресс, там нужно...

Как внедрить ProgressBar в макрос
Добрый день! почитал соседние темки на эту тему, нашел у товарища analyst архив с замечательными формами ProgressBar но так как...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Часы электронные
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С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru