abboudi_ammar Ответов: 1

Связать два окна в WPF + MVVM light


Добрый вечер, я пытаюсь связать окно WPF "MainWindow" с другим окном WPF, которое я называю "окном". Я написал код с помощью MVVMLight Toolkit и мой вопрос:подтверждает ли это шаблон проектирования MVVM, или как я могу его исправить?

Что я уже пробовал:

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

1 Ответов

Рейтинг:
0

Graeme_Grant

Нет, это неверно. Виртуальная машина не должна содержать никакого кода пользовательского интерфейса.

Есть много различных способов сделать то, что вы хотите. Мне нравится пользоваться классом обслуживания. Ниже приведен базовый (неполный) сервис, которым вы можете воспользоваться. Вам нужно будет обновить его для ваших нужд.

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();
        }
    }
}

Вот WindowDialog Окно для размещения "оконных видов":
<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>

Далее нам понадобится пара тестовых "оконных видов":
<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>

И соответствующие модели просмотра для "оконных видов":
class Window1ViewModel : ViewModelBase
{
    // The "Window View" VM code goes here...
}

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

Далее нам нужно связать виртуальные машины с представлениями. Вот я и делаю это в приложении.Xaml:
<Application.Resources>

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

    <DataTemplate DataType="{x:Type 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;
        }
    }
}

И главное окно для запуска теста:
<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>