如何从View模型打开View? [英] How to open View from View Model?

查看:61
本文介绍了如何从View模型打开View?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我是MVVM的初学者。我正在使用MVVM模式创建一个WPF应用程序。在具有一些内容和登录视图的MainWindow中。我想在MainWindow视图上打开Login View。用户必须先登录才能访问MainWindow的内容,但问题是我可以访问View from View模型。



如何解决这个问题?请帮助

解决方案

你不应该从ViewModel打开另一个视图,因为它违反MVVM模式,因为Hari p balineni已经说过了。因此,您可以将其转换为UserControl并将其转换为主窗口,而不是创建登录窗口,例如

< v:logincontrol x:name =   loginControl height =   270 width =   560 xmlns:x = < span class =code-string> #unknown xmlns:v =  #unknown /> 



和登录用户控件后面的代码



  public   partial   class  LoginControl:UserControl 
{
private UIElement parent;

private string 用户名;
private string 密码;


public ThreatBaseInformationTemplateV2()
{
InitializeComponent();
this .Visibility = System.Windows.Visibility.Hidden;
}

public void SetParent(UIElement parent)
{
.parent = parent;
}

public void ShowHandlerDailog()
{
this .Visibility = System.Windows.Visibility.Visible;
.parent.IsEnabled = false ;
}

public void HideHandlerDialog()
{
this .Visibility = System.Windows.Visibility.Hidden;
.parent.IsEnabled = true ;
}

private void btnLogin_Click( object sender,RoutedEventArgs e)
{
Username = txtUsername.Text;
Password = txtPassword.Text;
.parent.IsEnabled = true ;
this .Visibility = System.Windows.Visibility.Hidden;
}

private void btnCancel_Click( object sender,RoutedEventArgs e)
{
this .parent.IsEnabled = ;
this .Visibility = System.Windows.Visibility.Hidden;
}
}



现在,在MainWindow的构造函数中,您可以设置此控件的父级,如



this.loginControl.SetParent(KBEditor);



你可以在MainWindow的LoadEvent上显示它。



希望它会有所帮助。


在Viewmodel中打开视图是针对MVVM






也许这个例子可以帮助你达到你想要的效果。



不幸的是我不能在这里附上文件。



为了构建一个示例项目,请创建一个空的WPF项目。

添加以下文件夹:

普通,ViewModels,观看



公共文件夹:

Credentials.cs

 namespace MvvmOpenViewExample.Common 
{
public class Credentials
{
public string UserName {get;组; }
public string Password {get;组; }

public Credentials()
{
this.UserName = string.Empty;
this.Password = string.Empty;
}

public Credentials(string userName,string password)
{
this.UserName = userName;
this.Password =密码;
}
}
}





ViewModels文件夹:



IDialogProvider.cs

使用MvvmOpenViewExample.Common;使用System.Windows 
;

namespace MvvmOpenViewExample.ViewModels
{
public interface IDialogProvider
{
Credentials GetCredentials();

MessageBoxResult ShowMessageBox(字符串消息,字符串标题,MessageBoxButton messageBoxButton,MessageBoxImage messageBoxImage);
}
}





RelayCommand.cs

使用系统; 
使用System.Windows.Input;

namespace MvvmOpenViewExample.ViewModels
{
public class RelayCommand:ICommand
{
public RelayCommand(Action< object> execute)
:this (execute,null)
{

}

public RelayCommand(Action< object> execute,Predicate< object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}

public bool CanExecute(对象参数)
{
return(_canExecute!= null)? _canExecute(parameter):true;
}

public void执行(对象参数)
{
_execute(parameter);
}

公共事件EventHandler CanExecuteChanged
{
add {CommandManager.RequerySuggested + = value; }
remove {CommandManager.RequerySuggested - = value; }
}

private Action< object> _执行;
private Predicate< object> _canExecute;
}
}





ViewModel.cs

使用MvvmOpenViewExample.Common;使用System.Windows 
;
使用System.Windows.Input;

namespace MvvmOpenViewExample.ViewModels
{
public class ViewModel:ViewModelBase
{
#region Constructors

public ViewModel(IDialogProvider dialogProvider)
{
this.dialogProvider = dialogProvider;
}

#endregion

#region字段

IDialogProvider dialogProvider;

RelayCommand logInCommand;

#endregion

#region属性

公共ICommand LogInCommand
{
get
{
if(logInCommand == null)
{
logInCommand = new RelayCommand(param => this.LogIn());
}

返回logInCommand;
}
}

#endregion

#region方法

private void LogIn()
{
Credentials credentials = dialogProvider.GetCredentials();

if(credentials!= null)
{
dialogProvider.ShowMessageBox(登录成功!,信息,MessageBoxButton.OK,MessageBoxImage.Information);
}
else
{
dialogProvider.ShowMessageBox(登录已取消!,信息,MessageBoxButton.OK,MessageBoxImage.Information);
}
}

#endregion
}
}





ViewModelBase.cs

使用System;使用System.ComponentModel 
;

namespace MvvmOpenViewExample.ViewModels
{
public class ViewModelBase:INotifyPropertyChanged
{
[AttributeUsageAttribute(AttributeTargets.Parameter,Inherited = false)]
public sealed class CallerMemberNameAttribute:Attribute {}

public event PropertyChangedEventHandler PropertyChanged = delegate {};

public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if(PropertyChanged!= null)
{
PropertyChanged(this,new PropertyChangedEventArgs(propertyName的));
}
}
}
}





观看文件夹:



DialogProvider.cs

使用MvvmOpenViewExample.Common; 
使用MvvmOpenViewExample.ViewModels;使用System.Windows
;

namespace MvvmOpenViewExample.Views
{
public class DialogProvider:IDialogProvider
{
public Credentials GetCredentials()
{
LogInView logInView = new LogInView();

logInView.Owner = Application.Current.MainWindow;

logInView.ShowDialog();

返回logInView.credentials;
}

public MessageBoxResult ShowMessageBox(string message,string caption,MessageBoxButton messageBoxButton,MessageBoxImage messageBoxImage)
{
return MessageBox.Show(Application.Current.MainWindow,message ,caption,messageBoxButton,messageBoxImage);
}
}
}





LogInView.xaml

< pre lang =xml> < 窗口 x:Class = MvvmOpenViewExample.Views.LogInView

xmlns = http:// schemas。 microsoft.com/winfx/2006/xaml/presentation\"

xmlns:x = < span class =code-keyword> http://schemas.microsoft.com/winfx/2006/xaml

< span class =code-attribute> 标题 = 输入凭证

高度 = 225 < span class =code-attribute>

< span class =code-attribute> 宽度 = 350 ResizeMode = NoResize WindowStartupLocation = CenterOwner ShowInTaskbar = False 最顶层 = True >

< < span class =code-leadattribute> Window.Resources >
< 样式 TargetType = TextBlock >
< Setter 属性 = Horizo​​ntalAlignment = > < / Setter >
< Setter 属性 = VerticalAlignment = 中心 > < / Setter >
< Setter Property = 保证金 = 10 > < / Setter >
< / Style >
< 样式 TargetType = TextBox >
< Setter Property = Horizo​​ntalAlignment = 拉伸 > < / Setter >
< Setter 属性 = VerticalAlignment = 中心 > ; < / Setter >
< Setter 属性 = 保证金 < span class =code-attribute>
= 10 > < / Setter >
< / Style >
< 样式 TargetType = PasswordBox >
< Setter 属性 = Horizo​​ntalAlignment = 拉伸 &g t; < / Setter >
< Setter 属性 = VerticalAlignment = 中心 > < / Setter >
< Setter 属性 = 保证金 = 10 > < / Setter >
< Setter 属性 = 宽度 = 自动 > < / Setter >
< /样式 >
< 样式 < span class =code-attribute> TargetType = 按钮 >
< Setter 属性 = 宽度 = 75 > < / Setter >
< Setter 属性 = 高度 < span class =code-attribute> = 25 > < / Setter >
< Setter 属性 = 保证金 < span class =code-keyword> = 10 > < / Setter & gt;
< / Style >
< / Window.Resources >

< 网格 ShowGridLines = False >
< Grid.RowDefinitions >
< RowDefinition > < / RowDefinition >
< RowDefinition > < / RowDefinition >
< RowDefinition > < / RowDefinition >
< RowDefinition > < / RowDefinition >
< / Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition 宽度 = 1 * < span class =code-keyword>> < / ColumnDefinition >
< ColumnDefinition 宽度 = 3 * > < / ColumnDefinition >
< / Grid.ColumnDefinitions >
< TextBlock Grid.ColumnSpan = 2 文字 = 请输入您的用户名和密码。 >
< span class =code-keyword>< / TextBlock >
< TextBlock Grid.Row = 1 文本 = 用户名: > < / TextBlock >
< TextBlock Grid.Row = 2 文字 = 密码: > < < span class =code-leadattribute> / TextBlock >
< TextBox x:名称 = textBoxUserName Grid.Row = 1 Grid.Column = 1 > < / TextBox >
< PasswordBox x:名称 = passwordBox Grid.Row = 2 Grid.Column = 1 > < / PasswordBox >
< StackPanel Grid.Row = 3 Grid.ColumnSpan = 2 方向 = 何rizontal Horizo​​ntalAlignment = 中心 >
< Button x:Name< span class=\"code-keyword\">=\"buttonOK\" Content=\"OK\" Click=\"buttonOK_Click\"></Button>
<Button x:Name=\"buttonCancel\" Content=\"Cancel\" Click=\"buttonCancel_Click\"></Button>
</StackPanel>
</Grid>
</Window>





LogInView.xaml.cs

using MvvmOpenViewExample.Common; 
using System.Windows;

namespace MvvmOpenViewExample.Views
{
public partial class LogInView : Window
{
public Credentials credentials;

public LogInView()
{
InitializeComponent();
}

private void buttonOK_Click(object sender, RoutedEventArgs e)
{
credentials = new Credentials(textBoxUserName.Text, passwordBox.Password);

this.Close();
}

private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}





MainView.xaml

<Window x:Class=\"MvvmOpenViewExample.Views.MainView\" 

xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"

xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"

Title=\"MainView\" Height=\"350\" Width=\"525\">

<Grid>
<Button Width=\"75\" Height=\"25\" Margin=\"10\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Content=\"Log in\" Command=\"{Binding LogInCommand}\"></Button>
</Grid>
</Window>





MainView.xaml.cs

using System.Windows; 

namespace MvvmOpenViewExample.Views
{
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
}
}
}





The same place where the original App.xaml and App.xaml.cs were created by

Visual Studio:




App.xaml

<Application x:Class=\"MvvmOpenViewExample.App\" 

xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"

xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"

Startup=\"Application_Startup\">
<Application.Resources>

</Application.Resources>
</Application>





App.xaml.cs

using MvvmOpenViewExample.ViewModels; 
using MvvmOpenViewExample.Views;
using System.Windows;

namespace MvvmOpenViewExample
{
public partial class App : Application
{
ViewModel vm;
MainView mainView;

private void Application_Startup(object sender, StartupEventArgs e)
{
vm = new ViewModel(new DialogProvider());
mainView = new MainView();
mainView.DataContext = vm;
mainView.Show();
}
}
}





This example contains no model.



It shall only show how to use a dialog provider

which is called by using an interface.



Happy coding,

Stephan


Hi
I am a beginner when it comes to MVVM. I am creating a WPF application using MVVM pattern. In the a MainWindow that have some contents and a Login View. I want open Login View over MainWindow view. User have to login first to access the content of MainWindow but the problem is I can access the View from View model.

How I can solve this problem? Please help

解决方案

You should not open a another view from ViewModel because it is against the MVVM pattern as "Hari p balineni" already said. So, instead of Creating Login Window, You can convert it into the UserControl and place it into your main window like

<v:logincontrol x:name="loginControl" height="270" width="560" xmlns:x="#unknown" xmlns:v="#unknown" />


and at code behind of the Login UserControl

public partial class LoginControl : UserControl
   {
       private UIElement parent;

       private string Username;
       private string Password;


       public ThreatBaseInformationTemplateV2()
       {
           InitializeComponent();
           this.Visibility = System.Windows.Visibility.Hidden;
       }

       public void SetParent(UIElement parent)
       {
           this.parent = parent;
       }

       public void ShowHandlerDailog()
       {
           this.Visibility = System.Windows.Visibility.Visible;
           this.parent.IsEnabled = false;
       }

       public void HideHandlerDialog()
       {
           this.Visibility = System.Windows.Visibility.Hidden;
           this.parent.IsEnabled = true;
       }

       private void btnLogin_Click(object sender, RoutedEventArgs e)
       {
           Username = txtUsername.Text;
           Password = txtPassword.Text;
           this.parent.IsEnabled = true;
           this.Visibility = System.Windows.Visibility.Hidden;
       }

       private void btnCancel_Click(object sender, RoutedEventArgs e)
       {
           this.parent.IsEnabled = true;
           this.Visibility = System.Windows.Visibility.Hidden;
       }
   }


Now, In the constructor of the MainWindow you can set the parent of this control like

this.loginControl.SetParent(KBEditor);

and the you can show this on LoadEvent of MainWindow.

Hope it will help.


Openening View in Viewmodel is against MVVM


Hi,

maybe this example might help you to achieve what you want.

Unfortunately I cannot attach files here.

In order to build an example project please create an empty WPF project.
Add the following folders:
Common, ViewModels, Views

Common folder:
Credentials.cs

namespace MvvmOpenViewExample.Common
{
    public class Credentials
    {
        public string UserName { get; set; }
        public string Password { get; set; }

        public Credentials()
        {
            this.UserName = string.Empty;
            this.Password = string.Empty;
        }

        public Credentials(string userName, string password)
        {
            this.UserName = userName;
            this.Password = password;
        }
    }
}



ViewModels folder:

IDialogProvider.cs

using MvvmOpenViewExample.Common;
using System.Windows;

namespace MvvmOpenViewExample.ViewModels
{
    public interface IDialogProvider
    {
        Credentials GetCredentials();

        MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton messageBoxButton, MessageBoxImage messageBoxImage);
    }
}



RelayCommand.cs

using System;
using System.Windows.Input;

namespace MvvmOpenViewExample.ViewModels
{
    public class RelayCommand : ICommand
    {
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {

        }

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return (_canExecute != null) ? _canExecute(parameter) : true;
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        private Action<object> _execute;
        private Predicate<object> _canExecute;
    }
}



ViewModel.cs

using MvvmOpenViewExample.Common;
using System.Windows;
using System.Windows.Input;

namespace MvvmOpenViewExample.ViewModels
{
    public class ViewModel : ViewModelBase
    {
        #region Constructors

        public ViewModel(IDialogProvider dialogProvider)
        {
            this.dialogProvider = dialogProvider;
        }

        #endregion

        #region Fields

        IDialogProvider dialogProvider;

        RelayCommand logInCommand;

        #endregion

        #region Properties

        public ICommand LogInCommand
        {
            get
            {
                if (logInCommand == null)
                {
                    logInCommand = new RelayCommand(param => this.LogIn());
                }

                return logInCommand;
            }
        }

        #endregion

        #region Methods

        private void LogIn()
        {
            Credentials credentials = dialogProvider.GetCredentials();

            if(credentials != null)
            {
                dialogProvider.ShowMessageBox("Log in successful!", "Information", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                dialogProvider.ShowMessageBox("Log in cancelled!", "Information", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        #endregion
    }
}



ViewModelBase.cs

using System;
using System.ComponentModel;

namespace MvvmOpenViewExample.ViewModels
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        [AttributeUsageAttribute(AttributeTargets.Parameter, Inherited = false)]
        public sealed class CallerMemberNameAttribute : Attribute { }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}



Views folder:

DialogProvider.cs

using MvvmOpenViewExample.Common;
using MvvmOpenViewExample.ViewModels;
using System.Windows;

namespace MvvmOpenViewExample.Views
{
    public class DialogProvider : IDialogProvider
    {
        public Credentials GetCredentials()
        {
            LogInView logInView = new LogInView();

            logInView.Owner = Application.Current.MainWindow;

            logInView.ShowDialog();

            return logInView.credentials;
        }

        public MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton messageBoxButton, MessageBoxImage messageBoxImage)
        {
            return MessageBox.Show(Application.Current.MainWindow, message, caption, messageBoxButton, messageBoxImage);
        }
    }
}



LogInView.xaml

<Window x:Class="MvvmOpenViewExample.Views.LogInView"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Enter Credentials" 

        Height="225" 

        Width="350" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" Topmost="True">
    
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Left"></Setter>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="Margin" Value="10"></Setter>
        </Style>
        <Style TargetType="TextBox">
            <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="Margin" Value="10"></Setter>
        </Style>
        <Style TargetType="PasswordBox">
            <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="Margin" Value="10"></Setter>
            <Setter Property="Width" Value="Auto"></Setter>
        </Style>
        <Style TargetType="Button">
            <Setter Property="Width" Value="75"></Setter>
            <Setter Property="Height" Value="25"></Setter>
            <Setter Property="Margin" Value="10"></Setter>
        </Style>
    </Window.Resources>
    
    <Grid ShowGridLines="False">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="3*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.ColumnSpan="2" Text="Please enter your user name and password.">            
        </TextBlock>
        <TextBlock Grid.Row="1" Text="User Name:"></TextBlock>
        <TextBlock Grid.Row="2" Text="Password:"></TextBlock>
        <TextBox x:Name="textBoxUserName" Grid.Row="1" Grid.Column="1"></TextBox>
        <PasswordBox x:Name="passwordBox" Grid.Row="2" Grid.Column="1"></PasswordBox>
        <StackPanel Grid.Row="3" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center">
            <Button x:Name="buttonOK" Content="OK" Click="buttonOK_Click"></Button>
            <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click"></Button>
        </StackPanel>        
    </Grid>
</Window>



LogInView.xaml.cs

using MvvmOpenViewExample.Common;
using System.Windows;

namespace MvvmOpenViewExample.Views
{
    public partial class LogInView : Window
    {
        public Credentials credentials;

        public LogInView()
        {
            InitializeComponent();
        }

        private void buttonOK_Click(object sender, RoutedEventArgs e)
        {
            credentials = new Credentials(textBoxUserName.Text, passwordBox.Password);

            this.Close();
        }

        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}



MainView.xaml

<Window x:Class="MvvmOpenViewExample.Views.MainView"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainView" Height="350" Width="525">

    <Grid>
        <Button Width="75" Height="25" Margin="10" VerticalAlignment="Top" HorizontalAlignment="Left" Content="Log in" Command="{Binding LogInCommand}"></Button>
    </Grid>
</Window>



MainView.xaml.cs

using System.Windows;

namespace MvvmOpenViewExample.Views
{
    public partial class MainView : Window
    {
        public MainView()
        {
            InitializeComponent();
        }
    }
}



The same place where the original App.xaml and App.xaml.cs were created by
Visual Studio:


App.xaml

<Application x:Class="MvvmOpenViewExample.App"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             Startup="Application_Startup">
    <Application.Resources>
        
    </Application.Resources>
</Application>



App.xaml.cs

using MvvmOpenViewExample.ViewModels;
using MvvmOpenViewExample.Views;
using System.Windows;

namespace MvvmOpenViewExample
{
    public partial class App : Application
    {
        ViewModel vm;
        MainView mainView;

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            vm = new ViewModel(new DialogProvider());
            mainView = new MainView();                        
            mainView.DataContext = vm;
            mainView.Show();
        }
    }
}



This example contains no model.

It shall only show how to use a dialog provider
which is called by using an interface.

Happy coding,
Stephan


这篇关于如何从View模型打开View?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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