在WPF + MVVM灯中链接两个窗口 [英] Link two windows in WPF + MVVM light

查看:73
本文介绍了在WPF + MVVM灯中链接两个窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

晚上好,我尝试将窗口WPFMainWindow链接到另一个窗口WPF,我将其命名为window。我用MVVMLight Toolkit和我的问题编写了一个代码:这是否确认了MVVM设计模式,或者我该如何修复它?



我尝试过:



  public   MainViewModel:ViewModelBase 
{
public ICommand Save { get < /跨度>; set ; }
public MainViewModel()
{
Save = new RelayCommand (CommandSave);

}
private void CommandSave()
{
fenetre windows = new fenetre();
windows.Show();

}


}

解决方案

不,这是无效。 VM不应包含任何UI代码。



有许多不同的方法可以做你想要的。我喜欢使用服务类。以下是您可以使用的基本(不完整)服务。您需要根据需要更新它。

  public   interface  IWindowService 
{
void ShowWindow< T>(T viewModel);
}

public class WindowService:IWindowService
{
public void ShowWindow< T>(T viewModel)
{
var window = Application.Current
.Windows
.OfType< WindowDialog>()
.FirstOrDefault(x = > x.Content?.GetType()== viewModel.GetType());
if (window == null
{
window = new WindowDialog {Content = viewModel};
window.Title = 这是一个标题;
window.Owner = Application.Current.Windows [ 0 ];
window.Show();
}
else
{
window.Activate();
}
}
}



这是主机的 WindowDialog 窗口窗口视图:

 <   Window   

x:Class = MvvmShowWindow.WindowDialog

xmlns = http://schemas.microsoft.com/winfx/2006/xaml/presentatio n

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

mc:可忽略 = d



WindowStyle = SingleBorderWindow WindowStartupLocation = CenterOwner SizeToContent = WidthAndHeight >

< / Window >



接下来我们需要一些测试窗口视图:

 <   UserControl   

x:Class = MvvmShowWindow.Window1View

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

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

高度 = 300 宽度 = 600 >
< 网格 >
< Viewbox >
< TextBlock 文本 = WINDOW 1 / >
< / Viewbox >
< / Grid >
< span class =code-keyword>< / UserControl >

< UserControl

x:Class = MvvmShowWindow.Window2View

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

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

高度 = 300 宽度 = 600 >
< 网格 >
< Viewbox >
< TextBlock 文本 = WINDOW 2 / >
< / Viewbox >
< / Grid >
< / UserControl >



为窗口视图匹配ViewModels:

  class  Window1ViewModel:ViewModelBase 
{
// Window ViewVM代码在这里...
}

class Window2ViewModel:ViewModelBase
{
// Window View VM代码在这里......
}



接下来我们需要将VM与视图关联起来。我在App.Xaml中执行此操作:

 <   Application.Resources  >  

< < span class =code-leadattribute> DataTemplate DataType = {x:键入local:Window1ViewModel} >
< local:Window1View / >
< / DataTemplate >

< DataTemplate DataType = {x:键入local:Window2ViewModel} >
< local:Window2View / >
< / DataTemplate >

< / Application.Resources >



现在我们已准备好在MainViewModel中使用该服务:

  public   class  MainViewModel:ViewModelBase 
{
public MainViewModel()
{
ShowCommand = new RelayCommand< string> (CommandShow);
}

public ICommand ShowCommand { get ; }
private IWindowService Service = new WindowService();

private void CommandShow( string msg)
{
switch (msg)
{
case w1
Service.ShowWindow( new Window1ViewModel());
break ;

case w2
Service.ShowWindow( new Window2ViewModel());
break ;
}
}
}



和运行测试的MainWindow:

 <  窗口  

< span class =code-attribute> x:Class = MvvmShowWindow.MainWindow

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

xmlns:x < span class =code-keyword> = 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:local = clr-namespace:MvvmShowWindow

mc:可忽略 = d WindowStartupLocation = CenterScreen

标题 = MVVM Windows 高度 = 350 宽度 = 525 >

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

< 网格 >
< StackPanel VerticalAlignment = 中心 Horizo​​ntalAlignment = 中心 >
< 按钮 内容 = Window1 保证金 = 10 5 填充 = 10,5

< span class =code-attribute> 命令 = {Binding ShowCommand} CommandParameter = w1 / >
< 按钮 内容 = Window2 < span class =code-attribute>保证金 = 10 5 填充 = 10,5

命令 = {Binding ShowCommand} CommandParameter = w2 / >
< / StackPanel >
< / Grid >
< / Window > ;


Good evening, I try to link the window WPF "MainWindow" with another window WPF that I name it "window". I wrote a code with MVVMLight Toolkit and my question:does this confirm the MVVM design pattern, or how can I fix it?

What I have tried:

 public class MainViewModel : ViewModelBase
    {
        public ICommand Save { get; set; }
 public MainViewModel()
        {
Save = new RelayCommand(CommandSave);
 
        }
private void CommandSave()
        {
 fenetre windows = new fenetre();
            windows.Show();
 
        }
 
 
    }

解决方案

No, this is not valid. The VM should not contain any UI code.

There are many different ways of doing what you want. I like to use a service class. Below is a basic (incomplete) service that you can use. You will need to update it for your needs.

public interface IWindowService
{
    void ShowWindow<T>(T viewModel);
}

public class WindowService : IWindowService
{
    public void ShowWindow<T>(T viewModel)
    {
        var window = Application.Current
                             .Windows
                             .OfType<WindowDialog>()
                             .FirstOrDefault(x => x.Content?.GetType() == viewModel.GetType());
        if (window == null)
        {
            window = new WindowDialog { Content = viewModel };
            window.Title = "This is a title";
            window.Owner = Application.Current.Windows[0];
            window.Show();
        }
        else
        {
            window.Activate();
        }
    }
}


Here is the WindowDialog Window to host the "Window Views":

<Window

    x:Class="MvvmShowWindow.WindowDialog"

    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"

    mc:Ignorable="d"



    WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">

</Window>


Next we need a couple of test "Window Views":

<UserControl

    x:Class="MvvmShowWindow.Window1View"

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

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

    Height="300" Width="600">
    <Grid>
        <Viewbox>
            <TextBlock Text="WINDOW 1"/>
        </Viewbox>
    </Grid>
</UserControl>

<UserControl

    x:Class="MvvmShowWindow.Window2View"

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

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

    Height="300" Width="600">
    <Grid>
        <Viewbox>
            <TextBlock Text="WINDOW 2"/>
        </Viewbox>
    </Grid>
</UserControl>


And matching ViewModels for the "Window Views":

class Window1ViewModel : ViewModelBase
{
    // The "Window View" VM code goes here...
}

class Window2ViewModel : ViewModelBase
{
    // The "Window View" VM code goes here...
}


Next we need to associate the VMs with the Views. Here I do it in the App.Xaml:

<Application.Resources>

    <DataTemplate DataType="{x:Type local:Window1ViewModel}">
        <local:Window1View/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:Window2ViewModel}">
        <local:Window2View/>
    </DataTemplate>

</Application.Resources>


Now we are ready to use the service in the MainViewModel:

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        ShowCommand = new RelayCommand<string>(CommandShow);
    }

    public ICommand ShowCommand { get; }
    private IWindowService Service = new WindowService();

    private void CommandShow(string msg)
    {
        switch (msg)
        {
            case "w1":
                Service.ShowWindow(new Window1ViewModel());
                break;

            case "w2":
                Service.ShowWindow(new Window2ViewModel());
                break;
        }
    }
}


And the MainWindow to run the test:

<Window

    x:Class="MvvmShowWindow.MainWindow"

    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:local="clr-namespace:MvvmShowWindow"

    mc:Ignorable="d" WindowStartupLocation="CenterScreen"

    Title="MVVM Windows" Height="350" Width="525" >

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

    <Grid>
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <Button Content="Window1" Margin="10 5" Padding="10,5"

                    Command="{Binding ShowCommand}" CommandParameter="w1"/>
            <Button Content="Window2" Margin="10 5" Padding="10,5"

                    Command="{Binding ShowCommand}" CommandParameter="w2"/>
        </StackPanel>
    </Grid>
</Window>


这篇关于在WPF + MVVM灯中链接两个窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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