我的Window c#MVVM的重启按钮

时间:2016-04-21 06:04:08

标签: c# wpf mvvm

我试图为当前窗口设置一个重启按钮,但是当我按下它时,窗口会按原样关闭,程序会在gameWindow.Show()上停止并出现以下错误:类型未处理的异常PresentationFramework.dll中出现System.InvalidOperationException 附加信息:窗口关闭后,无法设置可见性或呼叫显示,ShowDialogWindowInteropHelper.EnsureHandle。 我有一个GameWindow和一个GameWindowViewModel我在其中为重启按钮和一个函数创建了ICommand

以下是我正在使用的代码:

 void restartButtonClickFunction(object obj)
{
    GameWindow gamewindow = new GameWindow();
    foreach (var window in Application.Current.Windows)
    {
        if (window is GameWindow)
        {
            ((Window)window).Close();
        }
    }
    gamewindow.Show();
}

4 个答案:

答案 0 :(得分:1)

IMO,最好重新设计您的应用程序。 我建议您将视图模型分开,而不是关闭主窗口并再次显示它。

创建游戏视图模型:

public class GameVm : ViewModelBase
{
    public GameVm()
    {
        var rnd = new Random();
        health = rnd.Next(100);
        armor = rnd.Next(100);
    }

    public int Health
    {
        get { return health; }
        set
        {
            if (health != value)
            {
                health = value;
                OnPropertyChanged();
            }
        }
    }
    private int health;

    public int Armor
    {
        get { return armor; }
        set
        {
            if (armor != value)
            {
                armor = value;
                OnPropertyChanged();
            }
        }
    }
    private int armor;
}

和应用程序视图模型:

public class ApplicationVm : ViewModelBase
{
    public ApplicationVm()
    {
        RestartGameCommand = new RelayCommand(() => Game = new GameVm());
        RestartGameCommand.Execute(null);
    }

    public GameVm Game
    {
        get { return game; }
        private set
        {
            if (game != value)
            {
                game = value;
                OnPropertyChanged();
            }
        }
    }
    private GameVm game;

    public ICommand RestartGameCommand { get; set; }
}

正如您所看到的,应用程序管理游戏生命周期 - 当RestartGameCommand被触发时,游戏会重新创建。

现在,这就是它在视图层的工作方式:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="100" Width="200">

    <Window.DataContext>
        <local:ApplicationVm />
    </Window.DataContext>

    <StackPanel>
        <!-- Game view placeholder -->
        <ContentControl Content="{Binding Game}">
            <ContentControl.ContentTemplate>
                <DataTemplate DataType="{x:Type local:GameVm}">
                    <StackPanel>
                        <TextBlock Text="{Binding Health}"/>
                        <TextBlock Text="{Binding Armor}"/>
                    </StackPanel>
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>
        <!-- Game controls pane -->
        <Button Content="Restart game" Command="{Binding RestartGameCommand}"/>
    </StackPanel>
</Window>

处理RestartGameCommand时,视图中的ContentControl将使用新的游戏视图模型进行初始化。

没有任何管理窗口的代码,但游戏重新开始。

答案 1 :(得分:0)

尝试这是否有效 没有经过测试,这是一个疯狂的猜测

void restartButtonClickFunction(object obj)
{

    foreach (var window in Application.Current.Windows)
    {
        if (window is GameWindow)
        {
            ((Window)window).Close();
        }
    }
    GameWindow gamewindow = new GameWindow();
    gamewindow.Show();
}

答案 2 :(得分:0)

错误告诉您问题是什么。您的MainWindow已经关闭,因此您之后无法执行其他操作。而是尝试重新运行该过程

void restartButtonClickFunction(object obj)
{
    Process.Start(Application.ResourceAssembly.Location);
    Application.Current.Shutdown();
}

或者您可以使用EventAggregaterGameWindowViewModel举起活动并在MainWindowViewModel中收听,然后您可以关闭并重启GameWindow

答案 3 :(得分:0)

我知道我来晚了,但是我解决了你的问题。我目前正在做相同的事情,但使用的是打牌游戏。下面的代码已经过测试,可以正常工作。

private void Btn_reset_Click(object sender, RoutedEventArgs e)
      var newwindow = new Game_Window();
      newwindow.Show();
      Close();
}