簡體   English   中英

MVVM WPF更改窗口並關閉上一個

[英]MVVM WPF change window and close the previous

作為MVVM所有架構的入門者,我對一個窗口到另一個窗口之間的導航存在一些疑問。 我正在使用Framework MVVM Light。

我期望的行為是在WinForms中,如下所示:

gw =新的GeneralWindow(); this.Hide(); //或關閉gw.Show();

我已經花了幾個小時試圖使用Messenger來找到一些提示,但是我發現我必須在視圖中使用代碼隱藏的方法,而這並不是非常MVVMish。

最好的問候,並在此先感謝您。

我期望的行為是在WinForms中,如下所示:

GeneralWindow gw = new GeneralWindow(); this.Hide(); // or close gw.Show();

MVVM模式將ViewViewModel分開。 因此,沒有資格從ViewModel創建新的View 從視圖模型創建窗口實例並顯示窗口違反了MVVM 。”因此,我建議您使用流行的技術,通過ContentControlDataTemplate更改Views

讓我們深入研究這種技術:

<Window>
   <Window.Resources>
      <DataTemplate DataType="{x:Type ViewModelA}">
         <localControls:ViewAUserControl/>
      </DataTemplate>
      <DataTemplate DataType="{x:Type ViewModelB}">
         <localControls:ViewBUserControl/>
      </DataTemplate>
   <Window.Resources>
  <ContentPresenter Content="{Binding CurrentView}"/>
</Window>

如果Window.DataContext是實例ViewModelA ,然后ViewA將會顯示出來, Window.DataContext是實例ViewModelB ,然后ViewB將被顯示。

讓我展示一個示例,可以看到應該將DataTemplates放在哪里:

<Window x:Class="SimpleMVVMExample.ApplicationView"
        ...The code omitted for the brevity...
        Title="Simple MVVM Example with Navigation" Height="350" Width="525">
    <Window.Resources>
       <DataTemplate DataType="{x:Type ViewModelA}">
         <localControls:ViewAUserControl/>
      </DataTemplate>
      <DataTemplate DataType="{x:Type ViewModelB}">
         <localControls:ViewBUserControl/>
      </DataTemplate>
    </Window.Resources>

    <DockPanel>
        <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
            <ItemsControl ItemsSource="{Binding ListOfViewModels}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}"
                                Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"
                                Margin="2,5"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Border>

        <ContentControl Content="{Binding CurrentDataTemplateViewModel}" />
    </DockPanel>
</Window>

我見過和讀過的最好的例子是雷切爾·林(Rachel Lim)。 參見示例。

更新:

如果要真正打開新窗口,則應創建一個中間層,以使ViewModel不依賴於創建新窗口的具體實現。

public class YourViewModel
{
    private readonly IWindowFactory windowFactory;
    private ICommand openNewWindow;

    public YourViewModel(IWindowFactory _windowFactory)
    {
        windowFactory = windowFactory;

        /**
         * Would need to assign value to m_openNewWindow here, and 
         * associate the DoOpenWindow method
         * to the execution of the command.
         * */
        openNewWindow = null;  
    }

    public void DoOpenNewWindow()
    {
        windowFactory.CreateNewWindow();
    }

    public ICommand OpenNewWindow { get { return openNewWindow; } }
}

public interface IWindowFactory
{
    void CreateNewWindow();
}

public class ProductionWindowFactory: IWindowFactory
{

    #region Implementation of INewWindowFactory

    public void CreateNewWindow()
    {
       NewWindow window = new NewWindow
           {
               DataContext = new NewWindowViewModel()
           };
       window.Show();
    }

    #endregion
}

如何關閉窗戶?

有很多方法。 其中之一是:

Application.Current.MainWindow.Close()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM