С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
 
HypSpace
3 / 3 / 1
Регистрация: 01.03.2017
Сообщений: 33
1

Доступ к свойствам из другой ViewModel [MVVM Light]

08.03.2017, 19:03. Просмотров 439. Ответов 3
Метки нет (Все метки)

Здравствуйте! Как получить доступ к свойствам одной ViewModel из другой ViewModel?
Использую MVVM Light. Долго гуглил, нашел, что нужно использовать Messenger, но почему-то не срабатывает.
Суть такова: когда открываю новое окно (в программе это очистка кэша), на панели задач должна бегать зеленая полоса по кнопке на панели задач.
Реализовал это свойство (в MainViewModel) через:
C#
1
2
3
4
5
6
7
private TaskbarItemProgressState _taskbarState;
 
public TaskbarItemProgressState TaskbarState
{
    get { return _taskbarState; }
    set { Set(ref _taskbarState, value); }
}
Из самой MainViewModel все работает, напрямую / через Messenger.

А из CleanWndViewModel прямой доступ к свойствам MainViewModel и через Messenger не получается.
Прямой доступ:
C#
1
2
3
4
5
6
7
MainViewModel _mainWndModel = (App.Current.Resources["Locator"] as ViewModelLocator).Main;
//Конструктор модели
public CleanWndViewModel()
{
     _mainWndModel.TaskbarState = TaskbarItemProgressState.Indeterminate;
    _mainWndModel.RaisePropertyChanged("TaskbarState");
}
Через Messenger:
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
//Конструктор модели CleanWndViewModel, из которого должно отправиться сообщение для изменения свойства
public CleanWndViewModel()
{
    Messenger.Default.Send<string>("DoIndeterminateTaskState");
}
//Главное окно - конструктор модели
public MainViewModel()
{
Messenger.Default.Register<string>(this, (message) =>
{
switch (message)
{
    case "DoIndeterminateTaskState":
        TaskbarState = TaskbarItemProgressState.Indeterminate;
        RaisePropertyChanged("TaskbarState");
    break;
    case "DoNoneTaskState":
        TaskbarState = TaskbarItemProgressState.None;
        RaisePropertyChanged("TaskbarState");
    break;
    default:
    break;
}
});
}
Ничего не происходит, увы, а должна бегать зеленая полоса по кнопке на панели задач.
Где я ошибся?
Спасибо.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.03.2017, 19:03
Ответы с готовыми решениями:

Подскажите, пожалуйста, где в MVVM поместить экземпляр ViewModel, чтобы к нему имели доступ несколько View?
Есть Model.cs. Есть ViewModel.cs. В ViewModel есть публичная коллекция Model и...

Mvvm ViewModel в ViewModel
Есть одно окошко там много вкладок, в каждой вкладке есть подвкладки и там...

MVVM и свойство из ViewModel
не могу понять где хранятся объекты из ViewModel есть класс с СМСками...

MVVM паттерн. Что такое ViewModel?
Всем доброго времени. Перехожу с winform на wpf и никак не могу понять что...

Viewmodel при использовании wpf и mvvm
Совсем недавно начал осваивать wpf и соответсвенно паттерн mvvm. Есть одно...

3
Casper-SC
Эксперт .NET
3638 / 1843 / 360
Регистрация: 27.03.2010
Сообщений: 5,169
Записей в блоге: 1
08.03.2017, 21:38 2
А не проще вызывать
C#
1
_mainWndModel.RaisePropertyChanged("TaskbarState");
В сеттере свойства? Так не то что проще, так и нужно
0
HypSpace
3 / 3 / 1
Регистрация: 01.03.2017
Сообщений: 33
08.03.2017, 21:44  [ТС] 3
Casper-SC, добрый вечер! Все равно не работает.
1) Функция Set(ref T field, T newValue) во фреймворке MVVM Light автоматически вызывает RaisePropertyChanged, добавление RaisePropertyChanged после этой функции ничего не меняет.
2) Все равно после того, как кэш очистится, бегущая полоса по кнопке на панели задач должна остановиться, а значит, нужно получить доступ к свойству MainViewModel из CleanWndViewModel.
0
Casper-SC
Эксперт .NET
3638 / 1843 / 360
Регистрация: 27.03.2010
Сообщений: 5,169
Записей в блоге: 1
09.03.2017, 00:31 4
HypSpace, да не, я знаю, что дело не в этом. Я просто сижу пробую, у меня тоже не работает, хотя в другом проекте работает. Странно.

Добавлено через 2 минуты
Короче, у меня нет времени заморачиваться. Вот рабочий код с проекта одного:
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.IO;
using System.Windows;
using FriendsInformer.Configuration;
using FriendsInformer.Model.Security;
using FriendsInformer.View;
using FriendsInformer.ViewModel;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Win32;
 
namespace FriendsInformer.Messaging
{
    internal class MessengerInitializer
    {
        public MessengerInitializer()
        {
            Messenger.Default.Register(this, new Action<GenericMessage<AppMessage>>(GenericMessageReceived));
        }
 
        private void GenericMessageReceived(GenericMessage<AppMessage> message)
        {
            switch (message.Content.Command)
            {
                case AppCommand.ShowMainWindow:
 
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        var window = new MainWindow();
                        var viewModel = (MainViewModel)window.DataContext;
                        window.Show();
                        Application.Current.MainWindow.Close();
                        Application.Current.MainWindow = window;
 
                        viewModel.Login((SecureAuthData)message.Content.Data);
                    });
                    break;
 
                case AppCommand.SignOut:
 
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        if (File.Exists(Config.Default.Files.AuthDataFile))
                            File.Delete(Config.Default.Files.AuthDataFile);
 
                        var authDialog = new AuthorizationDialog();
                        authDialog.Show();
                        Application.Current.MainWindow.Close();
                        Application.Current.MainWindow = authDialog;
                    });
                    break;
 
                case AppCommand.OpenFileDialog:
 
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        var dialog = new OpenFileDialog();
                        //dialog.
                        dialog.ShowDialog();
                    });
                    break;
 
                default:
                    return;
 
            }
        }
    }
}
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
namespace FriendsInformer.Messaging
{
    /// <summary>
    /// Содержит константные значения сообщений
    /// </summary>
    internal enum AppCommand
    {
        /// <summary> Показать новое окно </summary>
        ShowMainWindow,
 
        /// <summary> Выйти из аккаунта </summary>
        SignOut,
 
        /// <summary> Открыть окно выбора файла </summary>
        OpenFileDialog
    }
 
    internal class AppMessage : Message<AppCommand, object>
    {
        public AppMessage(AppCommand command, object content = null) 
            : base(command, content)
        {
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Windows;
using FriendsInformer.Messaging;
 
namespace FriendsInformer
{
    public partial class App : Application
    {
        private MessengerInitializer _messengerInitializer;
 
        private void App_OnStartup(object sender, StartupEventArgs e)
        {
            _messengerInitializer = new MessengerInitializer();
        }
    }
}
MainViewModel
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
        private void SignOut()
        {
            Messenger.Default.Send(new GenericMessage<AppMessage>(this, new AppMessage(AppCommand.SignOut)));
        }
 
        private void OpenFileDialog()
        {
            Messenger.Default.Send(new GenericMessage<AppMessage>(this, new AppMessage(AppCommand.OpenFileDialog)));
        }
 
        private void ApplicationShutdown()
        {
            Application.Current.Shutdown();
        }
 
        public RelayCommand SignOutCommand
        {
            get { return _signOutCommand ?? (_signOutCommand = new RelayCommand(SignOut)); }
        }
 
        public RelayCommand ExitCommand
        {
            get { return _exitCommand ?? (_exitCommand = new RelayCommand(ApplicationShutdown)); }
        }
 
        public RelayCommand OpenFolderCommand
        {
            get { return _openFolderCommand ?? (_openFolderCommand = new RelayCommand(OpenFileDialog)); }
        }
Добавлено через 2 часа 43 минуты
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace FriendsInformer.Messaging
{
    internal class Message<TCommandEnum, TData> 
        where TCommandEnum : struct
    {
        public Message(TCommandEnum command, TData data)
        {
            Command = command;
            Data = data;
        }
 
        public TCommandEnum Command { get; protected set; }
 
        public TData Data { get; protected set; }
    }
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.03.2017, 00:31

Паттерн MVVM. Взаимодействие ViewModel с View
Пишу приложение, используя паттерн mvvm. Есть солюшн, и в нем три проекта....

Messanger MVVM Light
Здравствуйте! Разбираюсь с MVVM Light. Никак не могу настроить передачу...

Mvvm Light. EventToCommand не срабатывает
Всё работает. кроме этой команды, то есть вью с вью моделью связаны точно...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru