Начал изучать паттерн MVVM для использования в программе. В частности, сейчас есть пустой каркас MainWindow с ContentPresenter и две View - AuthView, MainView. Соответственно есть и ViewModel каждой. При старте программы в окно сразу загружается AuthView (скриншот ниже).
Желаемый результат - по нажатию кнопки выполняется обращение к серверу, получение ответа. Если ответ положительный - эти элементы исчезают и сюда грузится MainView. И что-то я совсем запутался, где разместить эту функцию взаимодействия с сервером, и как при получении именно положительного ответа в функции сменить View. Весь код приведен далее. Подскажите, пожалуйста, как добиться этого результата? То, что есть, сделал по различным статьям и примерам реализации, ещё разобрался слабо, так что заранее извиняюсь за ошибки, буду рад, если укажете на них.
Помогите, пожалуйста!
MainWindow.xaml
<Window x:Class="QRScanner.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"
xmlns:local="clr-namespace:QRScanner"
mc:Ignorable="d"
Title="QRSCanner" Height="450" Width="800">
<Grid>
<ContentPresenter x:Name="OutputView" Margin="5"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using QRScanner.ViewModels;
using QRScanner.Views;
namespace QRScanner
{
public interface IMainWindowsCodeBehind
{
/// <summary>
/// Показ сообщения для пользователя
/// </summary>
/// <param name="message">текст сообщения</param>
void ShowMessage(string message);
/// <summary>
/// Загрузка нужной View
/// </summary>
/// <param name="view">экземпляр UserControl</param>
void LoadView(ViewType typeView);
}
public enum ViewType
{
Authorization,
Main
}
public partial class MainWindow : Window, IMainWindowsCodeBehind
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//загрузка стартовой View
LoadView(ViewType.Authorization);
}
public void LoadView(ViewType typeView)
{
switch (typeView)
{
case ViewType.Authorization:
//загружаем вьюшку, ее вьюмодель
AuthView view = new AuthView();
AuthViewModel vm = new AuthViewModel(this);
//связываем их м/собой
view.DataContext = vm;
//отображаем
this.OutputView.Content = view;
break;
case ViewType.Main:
MainView viewF = new MainView();
MainViewModel vmF = new MainViewModel(this);
viewF.DataContext = vmF;
this.OutputView.Content = viewF;
break;
}
}
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
}
}
AuthView.xaml
<UserControl x:Class="QRScanner.Views.AuthView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:QRScanner.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"></ColumnDefinition>
<ColumnDefinition Width="0.6*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="0.3*"></RowDefinition>
<RowDefinition Height="0.3*"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label x:Name="login_lbl" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10 0" Content="Логин:"></Label>
<TextBox x:Name="login_box" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="10 0" Width="200"></TextBox>
<Label x:Name="pass_lbl" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10 0" Content="Пароль:"></Label>
<TextBox x:Name="pass_box" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10 0" Width="200"></TextBox>
<Label x:Name="entry_status" Grid.ColumnSpan="2" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Auth_status}"></Label>
<Button x:Name="authorize" Grid.ColumnSpan="2" Grid.Row="3" Command="{Binding LoadMainViewCommand, Mode=OneTime}" CommandParameter="{Binding Auth_status}" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="30 10" Content="Войти" Click="authorize_Click"></Button>
</Grid>
</UserControl>
AuthView.xaml.cs
using QRScanner.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace QRScanner.Views
{
/// <summary>
/// Логика взаимодействия для AuthView.xaml
/// </summary>
public partial class AuthView : UserControl
{
public AuthView()
{
InitializeComponent();
}
private void authorize_Click(object sender, RoutedEventArgs e)
{
if (login_box.Text == "1")
entry_status.Content = "OK";
else
entry_status.Content = "NO";
}
}
}
AuthViewModel.cs
using QRScanner.ViewModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRScanner.ViewModels
{
class AuthViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private IMainWindowsCodeBehind _MainCodeBehind;
private string auth_status;
public AuthViewModel(IMainWindowsCodeBehind codeBehind)
{
if (codeBehind == null) throw new ArgumentNullException(nameof(codeBehind));
_MainCodeBehind = codeBehind;
}
/// <summary>
/// Переход к главному отображению
/// </summary>
private RelayCommand _LoadMainViewCommand;
public RelayCommand LoadMainViewCommand
{
get
{
return _LoadMainViewCommand = _LoadMainViewCommand ??
new RelayCommand(OnLoadMainView, CanLoadMainView);
}
}
private bool CanLoadMainView()
{
return true;
}
private void OnLoadMainView()
{
_MainCodeBehind.LoadView(ViewType.Main);
}
}
}
MainView.xaml
<UserControl x:Class="QRScanner.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:QRScanner.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label x:Name="test" Content="Hello!"></Label>
</Grid>
</UserControl>
MainViewModel.cs
using QRScanner.ViewModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRScanner.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private IMainWindowsCodeBehind _MainCodeBehind;
public MainViewModel(IMainWindowsCodeBehind codeBehind)
{
if (codeBehind == null) throw new ArgumentNullException(nameof(codeBehind));
_MainCodeBehind = codeBehind;
}
}
}

x:Nameи работайте с привязками. Также у кнопкиauthorizeу вас зачем то идет привязка к команде и событиюClick, оставьте что то одно (в строгом MVVM события по типуClickявляются нарушением). По поводу самого вопроса, мне лично он не понятен. Просто сделайте метод, который будет отправлять на сервер данные и выводить нужную информацию исходя из ответа и вызывайте его в команде логина. – EvgeniyZ Feb 25 '19 at 13:56AuthViewModelвзаимодействовать с ней. Если же это всего пару строк кода, то модель можно не создавать и в самомAuthViewModelреализовать работу с сервером. Отвечая на "Как реализовать загрузку другой View" - примерно так. – EvgeniyZ Feb 25 '19 at 18:22Authorize()для работы с сервером. – EvgeniyZ Feb 25 '19 at 19:54