Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/14: Рейтинг темы: голосов - 14, средняя оценка - 4.64
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
.NET Core

Передача из второстепенной VM в основную VM

19.01.2022, 09:02. Показов 3320. Ответов 33
Метки mvvm, wpf (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Ни как не могу сообразить как реализовать передачу данных между VM. Прикреплен тестовый проект.

Есть три VM (MainViewModel,LogViewModel,SecondViewMo del).

LogViewModel Это скорее всего модель ни как не могу разобрать что должно быть моделью, а что VM?

в MainViewModel создается ObservableCollection Logs куда по задумке должны писать логи основная MainViewModel и SecondViewModel.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class MainViewModel: BaseInpc
    {
        private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
        private readonly DispatcherTimer Timer_ReadConnecting = new DispatcherTimer();// Для подключения
 
        public MainViewModel()
        {
            Logs = new ObservableCollection<LogViewModel>();
            // Запускаем таймер 
            Timer_ReadConnecting.Start();
            Timer_ReadConnecting.Interval = TimeSpan.FromSeconds(10);
            Timer_ReadConnecting.Tick += Timer_ReadConnecting_Tick;
            // второстепенная модель
            SecondVM = new SecondViewModel();
        }
 
        //для ЛОГОВ
        private ObservableCollection<LogViewModel> _logs;
        public ObservableCollection<LogViewModel> Logs { get => _logs; set => Set(ref _logs, value); }
        public void AddLogs(LogViewModel log)
        {
            Logs.Add(log);
            Logs.OrderByDescending(o => o.Time);
        }
 
        private SecondViewModel _secondVM;
        public SecondViewModel SecondVM { get => _secondVM; set => Set(ref _secondVM, value); }
 
        private void Timer_ReadConnecting_Tick(object sender, EventArgs e)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                AddLogs(new LogViewModel()
                {
                    Time = DateTime.Now,
                    Fatality = FaultDirection.Info,
                    Messadge = $"Пишем из основной модели",
                    Mesto = "Main",
                });
            });
        }
    }
Как записать из второстепенной модели SecondViewModel в Logs?
Вложения
Тип файла: rar TestVM.rar (196.8 Кб, 3 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.01.2022, 09:02
Ответы с готовыми решениями:

Передача данных из dll в основную программу
Доброго времени суток. Суть вопроса проста. Есть глобальный хук, хранимый в dll. Есть программа которая устанавливает этот хук. Так вот,...

Передача данных из *.cs файла в основную форму
Здравствуйте. Вопрос следующий. Есть *.cs файл с методами прикрепленный к проекту. После выполнения метода мне нужно результат передать в...

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

33
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 10:54
Студворк — интернет-сервис помощи студентам
marat1905, Но такую отписку очень трудно реализовать - нужно внедрение слабых событий.
Поэтому обычно поступают по другому.
Такую подписку реализуют токо на вышестоящих уровнях, так как они знают когда удаляется ссылка на нижестоящий.

А когда нужно реализовать обратную зависимость, в нижестоящих используют для этого не конструктор, а внедряющий метод.
И при изменениях на вышестоящих уровнях вызывают это метод.


Dependency Injection

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public class SecondViewModel
    {
 
        public ObservableCollection<TestModel> Tests { get; }
            => testSource?.Test;
 
        private ITestSource testSource;
        public InjectDependencies(ITestSource testSource)
        {
 
            this.testSource = testSource;
            RaisePropertyChanged(nameof(Tests));
        }
    }
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
27
28
29
30
     public class MainViewModel: BaseInpc, ITestSource
    {
 
        public MainViewModel()
        {
 
            // второстепенная модель
            SecondVM = new SecondViewModel();
        }
 
        private ObservableCollection<TestModel> _tests;
        /// <summary>Кошелек наш </summary>
        public ObservableCollection<TestModel> Test
        {
            get => _tests;
            set
            {
                Set(ref _tests, value);
            }
        }
 
        private SecondViewModel _secondVM;
        public SecondViewModel SecondVM { get => _secondVM; set => Set(ref _secondVM, value); }
 
       ... OnProperryChanged ....
       {
              if(propertyName is nameof(Test) or nameof(SecondVM) && SecondVM != null)
                  SecondVM.InjectDependencies(this);
       }
    }
Добавлено через 1 минуту
Цитата Сообщение от marat1905 Посмотреть сообщение
Вывожу данные во view. В этой коллекции постоянно обновляются, добавляются записи или удаляются.
А как в дочерней VM принять данные и отслеживать что там меняются данные?
А причём здесь изменение коллекции и замена самой коллекции?
Это же совершенно разные вещи.
Второе тоже, конечно, бывает нужно.
Но очень редко, в каких-то исключительных задачах.
1
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 11:24  [ТС]
Элд Хасп,
Цитата Сообщение от Элд Хасп Посмотреть сообщение
public ObservableCollection<TestModel> Tests { get; }
            => testSource?.Test;
Выдает ошибку

Ошибка CS8057 Нельзя указывать тела блоков одновременно с телами выражений. TestVM C:\Users\BDM1\source\repos\TestVM\TestVM \ViewModel\SecondViewModel.cs 17 Активные
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
26.01.2022, 11:27
попробуйте без ">"
0
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 11:39  [ТС]
Элд Хасп, нашел. извиняюсь я косяк
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 12:57
Цитата Сообщение от marat1905 Посмотреть сообщение
Ошибка CS8057 Нельзя указывать тела блоков одновременно с телами выражений.
Писал здесь - случайная ошибка:
C#
1
public ObservableCollection<TestModel> Tests => testSource?.Test;
Добавлено через 1 минуту
Цитата Сообщение от limeniye Посмотреть сообщение
попробуйте без ">"
Нет.
Там нужно не присваивание, а явный геттер убрать.
Оператор => - это тоже упрощённое задание геттера для свойства.
А два геттера у свойства быть не может.

Добавлено через 42 секунды
marat1905, так какой из вариантов выбрали для реализации?
1
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 13:43  [ТС]
Элд Хасп, последний вариант выбрал. Все работает как хотелось. Только разобраться что да как это работает
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 17:44
Цитата Сообщение от marat1905 Посмотреть сообщение
Только разобраться что да как это работает
Там же просто всё.
Что непонятно?
0
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 18:07  [ТС]
Элд Хасп, Надо читать про интерфейсы. Значит на нижестоящих лучше использовать метод,

Цитата Сообщение от Элд Хасп Посмотреть сообщение
... OnProperryChanged ....
       {
              if(propertyName is nameof(Test) or nameof(SecondVM) && SecondVM != null)
                  SecondVM.InjectDependencies(this);
       }
А это где использовать?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 18:16
Цитата Сообщение от marat1905 Посмотреть сообщение
Надо читать про интерфейсы.
Интерфейс не обязательно.
Можно передавать и саму основную VM.... но как-то это очень криво.

Цитата Сообщение от marat1905 Посмотреть сообщение
А это где использовать?
В BaseInpc есть виртуальный метод OnProperryChanged.
Он используется для создания зависимосте.
Там откуда брали его, в том же посте есть объяснения и пример.

В Студии набираете protected override и Ctrl+пробел - Студия или сразу вставит метод или покажет список и из него выберите.
0
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 18:40  [ТС]
Элд Хасп,
Цитата Сообщение от Элд Хасп Посмотреть сообщение
public InjectDependencies(ITestSource testSource)
        {
this.testSource = testSource;
            RaisePropertyChanged(nameof(Tests));
        }
Выдает
Ошибка CS1520 Метод должен иметь тип возвращаемого значения TestVM C:\Users\BDM1\source\repos\TestVM\TestVM \ViewModel\SecondViewModel.cs 20 Активные
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 19:00
Цитата Сообщение от marat1905 Посмотреть сообщение
Выдает
Ошибка CS1520 Метод должен иметь тип возвращаемого значения
Писал здесь - пропустил void перед именем метода.
0
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 19:32  [ТС]
Элд Хасп,
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Писал здесь - пропустил void перед именем метода.
Спасибо большое.
Я так понял если нужно из дочернего класса передавать на главную то лучше с подпиской. а если обратная ситуация то так через метод?.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
26.01.2022, 19:55
Цитата Сообщение от marat1905 Посмотреть сообщение
Я так понял если нужно из дочернего класса передавать на главную то лучше с подпиской. а если обратная ситуация то так через метод?.
Да.
Вся загвоздка именно в подписке.
При подписке передаётся делегат метода.
В этом делегате есть ссылка на экземпляр откуда метод.
Поэтому если нужно удалить экземпляр, то нужно и удалить все его подписки.
А более-менее просто это можно сделать только в месте где создаётся/удаляется/добавляется экземпляр.
Так как добавление экземпляра в основную VM она может контролировать.
То основной VM подписаться/отписаться на события дочерней не трудно.
А вот обратная задача резко усложняется, так как дочерняя VM понятия не имеет кто её создал, кто содержит ссылку на неё, когда эти ссылки будут удаляться и т.д.

Это довольно сложно решается с помощью слабых событий, но проблема в том, что это должна быть реализация источника событий, а не слушателя.
Поэтому в данном случае, даже этот сложный механизм, всё равно не даст нужного результата.

Поэтому для "нисходящих" сообщений обычно реализуется последовательный вызов методов нижестоящих объектов.
1
1 / 1 / 1
Регистрация: 19.12.2016
Сообщений: 153
26.01.2022, 20:13  [ТС]
Элд Хасп, Спасибо большое за разъяснения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.01.2022, 20:13

Передача данных из Dll в основную программу
Есть dll в ней такой код : Получить данные из таблицы Db invoke mysql_real_query,hConn,SqlComm,lenn ; Выполняем операторSQL .if...

Передача значения массива в основную функцию
Программа написана через задницу, но прошу помочь лишь с одной ошибкой: Написать функцию, которая заполняет массив случайными числами....

Передача значений двух переменных в основную функцию
Доброго дня! Господа, поставлена задача: передать в функцию массив, найти минимальное и максимальное значение среди цифр его элеменов....

Передача данных из диалогового окна в основную форму
Здравствуйте дорогие форумчане. Из основной Activiti я вызываю диалоговое окно LayoutInflater layoutInflater =...

Процедура ввода динамического массива, передача его в основную программу
Хочу разбить на отдельные процедуры ввод и вывод массива символов для дальнейшей работы с ними. Код ниже работает не так как хочется:) ...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
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
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru