在WPF + MVVM灯中链接两个窗口 [英] Link two windows in WPF + MVVM light
问题描述
晚上好,我尝试将窗口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 = 中心 HorizontalAlignment = 中心 >
< 按钮 内容 = 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 theWindowDialog
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屋!