Без шаблона MVVM
, вызов нового окна в приложениях WPF
довольно прост:
// Обработчик кнопки открытия другого окна
void OpenOtherWindow(object sender, RoutedEventArgs e) {
OtherWindow otherWindow = new OtherWindow();
otherWindow.ViewModel = "ViewModel";
otherWindow.Show();
otherWindow.ShowViewModel();
}
// Другое окно
public partial class OtherWindow : Window {
public string ViewModel { get; set; }
public OtherWindow(){
InitializeComponent();
}
public void ShowViewModel(){
MessageBox.Show(ViewModel);
}
}
Предположим, что новое окно должно открываться как с помощью кнопки, так и сочетания клавиш. На данный момент, я могу предложить только такой способ:
MainWindowView.xaml (Элемент View)
<Window.CommandBindings>
<CommandBinding Command="local:AutomationCommands.OpenOtherWindow" Executed="OpenOtherWindow_Executed"/>
</Window.CommandBindings>
MainWindowView.xaml.cs
private void OpenOtherWindow_Executed(object sender, ExecutedRoutedEventArgs e) {
OtherWindow otherWindow = new OtherWindow();
otherWindow.ViewModel = "ViewModel";
otherWindow.Show();
otherWindow.ShowViewModel();
}
AutomationCommands.cs
public static RoutedCommand OpenList = new RoutedCommand("OpenOtherWindow", typeof(AutomationCommands), new InputGestureCollection(){
new KeyGesture(Key.N, ModifierKeys.Control)
});
Согласно концепции шаблона MVVM
, в MainWindowView.xaml.cs
особо логики быть не должно. Какие альтернативные, более правильные с точки зрения MVVM
подходы Вы можете преложить?
Несколько часов смотрел разные примеры по данной теме на разных языках. Все они либо неполные, потому не получается довести их до рабочего приложения, либо слишком сложные, а потому крайне трудны для понимания и адаптировать их под своё приложение, понимая при этом что делаешь, невозможно без помощи более опытных wpf-разработчиков. Потому, в данном конкурсе задача будет такая:
WPF
- честно говоря не понимаю, поэтому включите, пожалуйста, это объяснение в ответ). В новых окнах будет по одной надписи, что окно успешно открыто. Всё, больше нам в разметке ничего не нужно.
MVVM
, но в данном примере нам модель не нужна. Также не уведен, нужна ли ViewModel
но на всякий случай добавил соответствующие классы. Таким образом организация файлом будет такая (папка Models
присутствует, но она пустая):WPF
, их не поймут, а потому не смогут воспользоваться ими с понимаем. Нам нужен только код для открытия окон (в рамках MVVM
- с использование сервисов) а так же оповещение сервисов для закрытия окна.Заготовки кода:
MainWindowView.xaml - элемент View
главного окна
<Window x:Class="MVVM_OpenNewWindowMinimalExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="350">
<StackPanel>
<Button Content="Открыть обычное дочернее окно" Command="{Binding OpenChildWindow}"/>
<Button Content="Открыть диалоговое окно" Command="{Binding OpenDialogWindow}"/>
</StackPanel>
</Window>
MainWindowView.xaml.cs - это backcode
называется, да?
namespace MVVM_OpenNewWindowMinimalExample.Views {
public partial class MainWindowView : Window {
public MainWindowView() {
InitializeComponent();
}
}
}
App.xaml.cs
namespace MVVM_OpenNewWindowMinimalExample {
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
var modelView = new MainWindowView {
DataContext = new MainWindowViewModel()
};
modelView.Show();
}
}
}
Ссылка на Visual Studio-проект (Yandex Диск). Возможно, станет недоступной через некоторое время после окончания конкурса.
Очень хороший вопрос. Открытие новых окон — это сложный момент в рамках паттерна MVVM.
Смотрите. С одной стороны, решение об открытии нового окна принадлежит уровню бизнес-логики, то есть, VM. С другой стороны, VM не имеет права ничего знать о View. Получается противоречие.
Обычно это противоречие решают, создавая дополнительный сервис открытия окон, который настраивается в начале работы программы, и лежит между VM и View. С таким подходом VM-код создаёт VM-объект некоторого типа, и просит сервис обеспечить показ. Сервис проверяет тип объекта, создаёт окно нужного типа, и показывает его, установив переданный объект в качестве DataContext
.
Пример кода, реализующего этот подход, можно найти здесь (и посмотрите связанные вопросы).
Вам ещё придётся организовывать логику, оповещающую сервис о закрытии окна (и, возможно, запрашивающую подтверждение этого в VM).
Как вариант, можно воспользоваться классическим паттерном "Команда", как показано здесь. Тогда, в идеале, можно достичь того, что в представлении останется только инициализация модели представления.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Решил попробовать написать To do list, и столкнулся с проблемойНе знаю как сохранить созданные записи, не только в текстовом виде, а еще с CheckBox'ом,...
Не могу получить кусок текста с найденным запросомПолучаю ошибку
Я делаю калькулятор , но так как числа могут быть и float и int , я не знаю , во что мне конвертировать два числаДумал что double это и int и float , а нет))