Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 06.05.2015
Сообщений: 7
1
WPF

Активация окна из ViewModel

07.03.2019, 12:49. Показов 2578. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть ли лучший способ сделать активацию окна из под ViewModel? (желательно не нарушая принципы MVVM)

MainViewModel.cs
C#
1
public Action ActivateWindow;
MainWindow.xaml
XML
1
2
3
<Window.DataContext>
        <vm:MainViewModel/>
</Window.DataContext>
MainWindow.xaml.cs

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public partial class MainWindow : Window
    {
        MainViewModel ViewModel { get; set; }
 
        public MainWindow()
        {
            InitializeComponent();
 
            ViewModel = (DataContext as MainViewModel);
            ViewModel.ActivateWindow += ViewModel_Activate;
        }
 
        void ViewModel_Activate()
        {
            Dispatcher.Invoke(Activate);
        }
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.03.2019, 12:49
Ответы с готовыми решениями:

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

Открытие дочернего окна, передача данных между ViewModel-ями окон
Добрый день. Есть концептуальный вопрос по разработке приложений с использованием паттерна MVVM. А...

Как сделать при нажатии на кнопку (отправлении команды во ViewModel) Cursor.Wait у окна?
Здравствуйте, возникла жуткая потребность, чтобы сделать при нажатии на кнопку (отправлении команды...

(GalaSoft.MvvmLight) В одном окне используются 2 ViewModel. Вылетает исключение при создании окна
Здравствуйте. В общем, есть главное окно, DataContext которого: DataContext=&quot;{Binding...

7
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
07.03.2019, 13:19 2
Лучший ответ Сообщение было отмечено Casper-SC как решение

Решение

Цитата Сообщение от Serhiy_as Посмотреть сообщение
желательно не нарушая принципы MVVM
Данный подход не нарушает MVVM. Но обычно принято, чтобы файлах *.xaml.cs оставался только конструктор с вызовом InitializeComponents. Поэтому всю логику следует выносить в Behavior'ы.
Нужно подключить System.Windows.Interactivity.dll

Релизация:
XML
1
2
3
4
5
<Window>
    <i:Interaction.Behaviors>
        <behaviors:ActivateWindowBehavior />
    </i:Interaction.Behaviors>
</Window>
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
public class ActivateWindowBehavior : Behavior<Window>
{
    private MainViewModel _mainVM;
 
    public void OnAttached()
    {
        _mainVM = AssotiatedObject.DataContext as MainViewModel;
        if (_mainVM == null)
            return;
            
        _mainVM.ActivateWindow += ViewModel_Activate;
    }
    
    public void OnDetaching()
    {
        if (_mainVM == null)
            return;
            
        _mainVM.ActivateWindow -= ViewModel_Activate;
    }
    
    private void ViewModel_Activate()
    {
        AssotiatedObject.Dispatcher.Invoke(() => 
        {
            AssotiatedObject.Activate();
        });
    }
}
1
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,539
Записей в блоге: 2
07.03.2019, 13:27 3
Цитата Сообщение от Serhiy_as Посмотреть сообщение
Есть ли лучший способ сделать активацию окна из под ViewModel? (желательно не нарушая принципы MVVM)
Ну, теоретически, VM не должна сама обращаться к View.

Пара вариантов:
  • Привязать IsFocused и Visibility окна к свойствам VM
  • Создать дополнительное DP свойство в Window, в котором при изменении происходит активация окна. Это свойство привязать к свойству VM.
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
07.03.2019, 14:50 4
Лучший ответ Сообщение было отмечено Casper-SC как решение

Решение

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну, теоретически, VM не должна сама обращаться к View
Вы правы. Но в примере Serhiy_as ViewModel не обращается к View.
Свойство IsFocused имеет только get. А значит его нельзя изменить из ViewModel'и с помощью привязки.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Создать дополнительное DP свойство в Window, в котором при изменении происходит активация окна. Это свойство привязать к свойству VM.
Не лучший вариант реализации. Запрос на активацию окна - это событие, значит ViewModel и должна посылать событие, а не изменять свойства. Вот предположим, мы реализовали это через изменение свойства. Что нужно писать в свойство? Каждый раз какие-то новые рандомные значения? Согласитесь, что это не годится для серьёзного приложения

Добавлено через 58 минут
А ещё лучше сделать через Interaction.Triggers:

Отлавливаем событие ActivateWindow у DataContext'а
XML
1
2
3
4
5
6
7
<Window>
    <i:Interaction.Triggers>
        <i:EventTrigger SourceObject="{Binding DataContext}" EventName="ActivateWindow">
            <ActivateWindowTriggerAction />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Window>
Вызываем TriggerAction
C#
1
2
3
4
5
6
7
public class ActivateWindowTriggerAction : TriggerBase<Window>
{
    protected override void Invoke(object parameter){
    {
        AssociatedObject.Activate();
    }
}
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,539
Записей в блоге: 2
07.03.2019, 15:37 5
Цитата Сообщение от novikov.ea Посмотреть сообщение
Свойство IsFocused имеет только get.
Да, действительно. Не пользовался, а проверить поленился. Моя ошибка.

Цитата Сообщение от novikov.ea Посмотреть сообщение
Но в примере Serhiy_as ViewModel не обращается к View
Я думал
C#
10
ViewModel.ActivateWindow += ViewModel_Activate;
Это и есть создание обратной связи, по которой VM будет потом обращаться к окну.
Или я ошибаюсь?
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
08.03.2019, 09:00 6
Да. При подписке на событие ViewModel будет хранить ссылку на View. Но это не нарушает уровни абстракции, так как ViewModel не будет знать о типе View. События как раз и существуют, чтобы на них могли подписываться объекты более высокого уровня абстракции, так как напрямую взаимодействовать с объектами более высокого уровня, не нарушая уровни абстракции, не получится.
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,539
Записей в блоге: 2
08.03.2019, 10:11 7
Цитата Сообщение от novikov.ea Посмотреть сообщение
Да. При подписке на событие ViewModel будет хранить ссылку на View. Но это не нарушает уровни абстракции, так как ViewModel не будет знать о типе View. События как раз и существуют, чтобы на них могли подписываться объекты более высокого уровня абстракции, так как напрямую взаимодействовать с объектами более высокого уровня, не нарушая уровни абстракции, не получится.
А не лучше, если уж возникала такая потребность, просто подписаться на PropertyChange?
В чём смысл ввода нового события (или делегата)?
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
08.03.2019, 17:12 8
PropertyChanged тоже можно использовать как уведомление на активацию окна. Но если есть конкретный сценарий с конкретной потребностью на активацию окна, то будет более ясным и очевидным сделать отдельное событие, которое будет иметь вполне ясное и чёткое имя, отображающее конкретную суть данного события.
1
08.03.2019, 17:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.03.2019, 17:12
Помогаю со студенческими работами здесь

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

Активация окна
Прошу помощи ребята. Много перерыл не могу найти ответа. Set SH = CreateObject(&quot;WScript.Shell&quot;)...

Активация окна формы
Уважаемые знатоки! Подскажите как активировать окно формы после завершения исполнения по нажатию...

Активация модального окна
Всем привет ! я использую фреймворк boostrap 3 нужен такой способ но как сделать правильно не...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru