Ich versuche, MVVM zu lernen, aber es ist ein Alptraum, der versucht, zu verstehen, wie man zwischen Ansichten in einer Anwendung mit MVVM korrekt navigiert. Nach einiger Zeit Recherche und Versuch, verschiedene Techniken zu verstehen, bin ich auf einen Ansatz von Rachel Lim's blog gestoßen. Diese Technik verwendet ein ViewModel für die Anwendung selbst und verfolgt den Anwendungsstatus wie die aktuelle Seite. Ich denke, das wäre ein guter Ansatz für meine Bewerbung.So ändern Sie die Hauptfensteransicht von einem Popup-Fenster
Jetzt auf mein Problem zu bewegen ..
Was ich
Ich möchte eine Anwendung erreichen wollen, die eine eine Hauptansicht hat, die eine Loginview und ein Homeview als Datatemplates gespeichert werden und haben eine Inhaltssteuerung, die das LoginView als die Ansicht festlegt, die beim Start der Anwendung angezeigt wird. Die LoginView verfügt über eine Schaltfläche, die bei Betätigung ein weiteres Fenster mit einer Schaltfläche öffnet. Wenn die Schaltfläche im Popup-Fenster gedrückt wird, möchte ich die Ansicht im Hauptanwendungsfenster von LoginView auf HomeView ändern.
Was ich bisher haben
Ich habe die ApplicationView eingerichtet, die gut funktioniert.
<Window x:Class="WPF_Navigation_Practice.Views.ApplicationView"
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:ignore="http://www.galasoft.ch/ignore"
xmlns:vm="clr-namespace:WPF_Navigation_Practice.ViewModels"
xmlns:views="clr-namespace:WPF_Navigation_Practice.Views"
mc:Ignorable="d ignore"
DataContext="{StaticResource ApplicationViewModel}">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:LoginViewModel}">
<views:LoginView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:HomeViewModel}">
<views:HomeView />
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding CurrentPageViewModel}" />
</Grid>
</Window>
Und haben das ApplicationViewModel wie folgt eingerichtet. Einstellen der aktuellen Seite auf das LoginViewModel.
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using WPF_Navigation_Practice.Interfaces;
namespace WPF_Navigation_Practice.ViewModels
{
/// <summary>
/// This class contains properties that a View can data bind to.
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class ApplicationViewModel : ViewModelBase
{
#region Fields
private ICommand _changePageCommand;
private IPageViewModel _currentPageViewModel;
private List<IPageViewModel> _pageViewModels;
#endregion
public ApplicationViewModel()
{
// Add available pages
PageViewModels.Add(new LoginViewModel());
PageViewModels.Add(new HomeViewModel());
PageViewModels.Add(new CodeViewModel());
// Set starting page
CurrentPageViewModel = PageViewModels[0];
}
#region Properties/Commands
public ICommand ChangePageCommand
{
get
{
if (_changePageCommand == null)
{
_changePageCommand = new RelayCommand<object>(
p => ChangeViewModel((IPageViewModel)p),
p => p is IPageViewModel);
}
return _changePageCommand;
}
}
public List<IPageViewModel> PageViewModels
{
get
{
if (_pageViewModels == null)
_pageViewModels = new List<IPageViewModel>();
return _pageViewModels;
}
}
public IPageViewModel CurrentPageViewModel
{
get
{
return _currentPageViewModel;
}
set
{
if (_currentPageViewModel != value)
{
_currentPageViewModel = value;
RaisePropertyChanged("CurrentPageViewModel");
}
}
}
#endregion
#region Methods
private void ChangeViewModel(IPageViewModel viewModel)
{
if (!PageViewModels.Contains(viewModel))
PageViewModels.Add(viewModel);
CurrentPageViewModel = PageViewModels
.FirstOrDefault(vm => vm == viewModel);
}
#endregion
}
}
Wenn ich die Anwendung ausführen wird es mein Hauptfenster angezeigt werden, die die Loginview anzeigt, die ein Benutzersteuerelement ist und als currentPageViewModel mit Content gesetzt.
Wenn der Button im LoginView UserControl angeklickt wird, öffnet sich ein weiteres Fenster. Wie auf dem Bild unten. Hier
ist das XAML für das Fenster.
<Window x:Class="WPF_Navigation_Practice.Views.CodeView"
x:Name="CodeWindow"
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:ignore="http://www.galasoft.ch/ignore"
xmlns:z="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:viewModels="clr-namespace:WPF_Navigation_Practice.ViewModels"
mc:Ignorable="d ignore"
d:DesignWidth="623.224" d:DesignHeight="381.269"
DataContext="{Binding CodeViewModel, Source={StaticResource ApplicationViewModel}}">
<Grid>
<Button Content="Ok"
HorizontalAlignment="Left"
Margin="235,166,0,0"
VerticalAlignment="Top"
Width="138"
FontSize="20"
Height="67"/>
<Label Content="Second Window" HorizontalAlignment="Left" Margin="166,56,0,0" VerticalAlignment="Top" FontSize="36"/>
</Grid>
Mein Problem
Was ich will, ist zu erreichen, wenn die ‚OK‘ Taste im secondView Fenster geklickt wird, möchte ich von der die currentPageViewModel im ApplicationView Fenster ändern LoginView, um den HomeView anzuzeigen, bin aber verwirrt darüber, wie ich das erreichen würde. Jede Hilfe würde sehr geschätzt werden.
Ich könnte der Loginansicht ein LoggedIn-Ereignis geben, das die Hauptansicht abonniert. Wenn dies ausgelöst wird, kann die Hauptansicht dem Anwendungsansichtsmodell mitteilen, dass sich jemand angemeldet hat, indem Sie eine Eigenschaft (it == app vm) festlegen und eine Methode aufrufen, was auch immer. Es sollte ein Viewmodel geben, um alle zu regeln, wer Entscheidungen darüber trifft, was zu tun ist, wenn sich der Benutzer anmeldet - ich gehe davon aus, dass dies das Anwendungsansichtsmodell ist. –
MVVM ist ehrlich gesagt nicht gut für mehrere Fenster (einschließlich Dialoge usw.) ausgelegt. Verwenden Sie nach Möglichkeit ein einzelnes Fenster und schließen Sie verschiedene Benutzersteuerelemente an (jeweils eine Ansicht). – Jai
Probleme beim Übergeben des Hauptfensters als Parameter an den Konstruktor des Popup-Fensters und Festlegen der Ansicht von dort aus mit der Eigenschaft des Hauptfensters. – AnjumSKhan