从视图模型关闭窗口 [英] Close Window from ViewModel

查看:98
本文介绍了从视图模型关闭窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即时通讯使用窗口控制来允许用户登录到我是一个 WPF 应用程序创建一个登录创造。

Im creating a Login using a window control to allow a user to login into a WPF application that I am creating.

到目前为止,我已经创建了检查用户是否在正确的凭据输入的用户名密码文本在登录屏幕上,结合两个属性

So far, I have created a method that checks whether the user has entered in the correct credentials for the username and password in a textbox on the login screen, binding two properties.

我已经通过创建一个实现了这个布尔方法,像这样;

I have achieved this by creating a bool method, like so;

 public bool CheckLogin()
 {
        var user = context.Users.Where(i => i.Username == this.Username).SingleOrDefault();

        if (user == null)
        {
            MessageBox.Show("Unable to Login, incorrect credentials.");
            return false;
        }
        else if (this.Username == user.Username || this.Password.ToString() == user.Password)
        {
            MessageBox.Show("Welcome "+ user.Username + ", you have successfully logged in.");

            return true;
        }
        else
        {
            MessageBox.Show("Unable to Login, incorrect credentials.");
            return false;
        }
 }

 public ICommand ShowLoginCommand
 {
     get
     {
         if (this.showLoginCommand == null)
         {
             this.showLoginCommand = new RelayCommand(this.LoginExecute, null);
         }
         return this.showLoginCommand;
     }
 }

 private void LoginExecute()
 {
      this.CheckLogin();
 } 

我也有一个命令绑定 XAML中我的按钮像这样;

<Button Name="btnLogin" IsDefault="True" Content="Login" Command="{Binding ShowLoginCommand}" />

当我在输入用户名和密码,它执行拨款code,不管它是正确的,还是错误。但我怎么可以从视图模型关闭此窗口当两个用户名和密码是否正确?

When I enter in the username and password it executes the appropriated code, whether it being right, or wrong. But how can I close this window from the ViewModel when both username and password are correct?

我有$ P $使用对话模式 pviously尝试,但它并没有完全工作了。此外,我的App.xaml内,我已经做了类似以下,其中第一,那么一旦真实加载登录页面,加载实际应用。

I have previously tried using a dialog modal but it didn't quite work out. Furthermore, within my app.xaml, I have done something like the following, which loads the login page first, then once true, loads the actual application.

 private void ApplicationStart(object sender, StartupEventArgs e)
    {
        Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;

        var dialog = new UserView();

        if (dialog.ShowDialog() == true)
        {
            var mainWindow = new MainWindow();
            Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
            Current.MainWindow = mainWindow;
            mainWindow.Show();
        }
        else
        {
            MessageBox.Show("Unable to load application.", "Error", MessageBoxButton.OK);
            Current.Shutdown(-1);
        }
    }

所以,下面到我的问题 - 我怎样才能关闭登录窗口控制从视图模型

先谢谢了。

推荐答案

您可以直接在窗口中使用 CommandParameter 传递给您的视图模型。请参阅下面我举的例子:

You can simply pass the window to your ViewModel using the CommandParameter. See my Example below:

我实现了一个 CloseWindow 方法,它需要一个Windows作为参数,并关闭它。该窗口通过 CommandParameter 传递到视图模型。请注意,您需要定义一个 X:名称为这应该是关闭窗口。在我的XAML窗口,我呼吁通过命令此方法并传入窗口本身作为参数传递给视图模型使用 CommandParameter

I've implemented an CloseWindow Method which takes a Windows as parameter and close it. The window is passed to the ViewModel via CommandParameter. Note that you need to define an x:Name for the window which should be close. In my XAML Window i call this method via Command and pass the window itself as a parameter to the ViewModel using CommandParameter.

Command="{Binding CloseWindowCommand, Mode=OneWay}" 
CommandParameter="{Binding ElementName=TestWindow}"

这是一个干净,简单的解决方案是在遵守MVVM编程范例。

It is a clean and easy solution which is in compliance with the MVVM programming paradigm.

视图模型

public RelayCommand<Window> CloseWindowCommand { get; private set; }

public MainViewModel()
{
    this.CloseWindowCommand = new RelayCommand<Window>(this.CloseWindow);
}

private void CloseWindow(Window window)
{
    if (window != null)
    {
       window.Close();
    }
}

XAML

<Window x:Class="ClientLibTestTool.ErrorView"
        x:Name="TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:localization="clr-namespace:ClientLibTestTool.ViewLanguages"
        DataContext="{Binding Main, Source={StaticResource Locator}}"
        Title="{x:Static localization:localization.HeaderErrorView}" Height="600" Width="800" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
    <Grid> 
        <Button Content="{x:Static localization:localization.ButtonClose}" 
                Height="30" 
                Width="100" 
                Margin="0,0,10,10" 
                IsCancel="True" 
                VerticalAlignment="Bottom" 
                HorizontalAlignment="Right" 
                Command="{Binding CloseWindowCommand, Mode=OneWay}" 
                CommandParameter="{Binding ElementName=TestWindow}"/>
    </Grid>
</Window>

请注意,我使用的MVVM光框架,但主要是为每一个WPF应用程序相同的。

Note that i'm using the MVVM light framework, but the principal is the same for every wpf application.

编辑:

您登录按钮(新增CommandParameter):

Your Login Button (Added CommandParameter):

<Button Name="btnLogin" IsDefault="True" Content="Login" Command="{Binding ShowLoginCommand}" CommandParameter="{Binding ElementName=LoginWindow}"/>

您code:

 public RelayCommand<Window> CloseWindowCommand { get; private set; } // the <Window> is important for your solution!

 public MainViewModel() 
 {
     //initialize the CloseWindowCommand. Again, mind the <Window>
     //you don't have to do this in your constructor but it is good practice, thought
     this.CloseWindowCommand = new RelayCommand<Window>(this.CloseWindow);
 }

 public bool CheckLogin(Window loginWindow) //Added loginWindow Parameter
 {
    var user = context.Users.Where(i => i.Username == this.Username).SingleOrDefault();

    if (user == null)
    {
        MessageBox.Show("Unable to Login, incorrect credentials.");
        return false;
    }
    else if (this.Username == user.Username || this.Password.ToString() == user.Password)
    {
        MessageBox.Show("Welcome "+ user.Username + ", you have successfully logged in.");
        this.CloseWindow(loginWindow); //Added call to CloseWindow Method
        return true;
    }
    else
    {
        MessageBox.Show("Unable to Login, incorrect credentials.");
        return false;
    }
 }

 //Added CloseWindow Method
 private void CloseWindow(Window window)
 {
     if (window != null)
     {
         window.Close();
     }
 }

EDIT2:
用户的 CRONO 中提到的注释部分的有效点:

the user Crono mentions a valid point in the comment section:

传递窗口对象视图模型打破MVVM模式
  恕我直言,因为它迫使你的虚拟机知道它在被查看。

Passing the Window object to the view model breaks the MVVM pattern IMHO, because it forces your vm to know what it's being viewed in.

您可以通过引入包含close方法的接口解决这个问题。

You can fix this by introducing an interface containing a close method.

接口:

public interface IClosable
{
    void Close();
}

您重构视图模型将如下所示:

Your refactored ViewModel will look like this:

视图模型

public RelayCommand<IClosable> CloseWindowCommand { get; private set; }

public MainViewModel()
{
    this.CloseWindowCommand = new RelayCommand<IClosable>(this.CloseWindow);
}

private void CloseWindow(IClosable window)
{
    if (window != null)
    {
        window.Close();
    }
}

您需要参考/实施 IClosable 接口视图,以及
视图(code后面)

You need reference/implement the IClosable interface your view as well View (Code behind)

public partial class MainWindow : Window, IClosable
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

这篇关于从视图模型关闭窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆