Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:

C#
 public class MainViewModel : ViewModelBase
    {
        public ICommand Save { get; set; }
 public MainViewModel()
        {
Save = new RelayCommand(CommandSave);
 
        }
private void CommandSave()
        {
 fenetre windows = new fenetre();
            windows.Show();
 
        }
 
 
    }
Posted
Updated 27-Feb-18 3:02am

1 solution

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.
C#
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":
XML
<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":
XML
<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":
C#
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:
XML
<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:
C#
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:
XML
<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>
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900