1
votes

This question is in reference to this link Opening new window in MVVM WPF.

If I have the following:

public class WindowService:IWindowService {
     public void ShowWindow(object viewModel){
         var win = new Window {Content = viewModel};
         win.Show();
     }
}

and my app.xaml code:

<DataTemplate DataType="{x:Type local:MyViewModel}">
        <local:MyUserControlView  />
</DataTemplate>

I don't want to add style in the code as follow:

 public class WindowService:IWindowService {
     public void ShowWindow(object viewModel){
         var win = new Window {Content = viewModel};
         win.SizeToContent = SizeToContent.WidthAndHeight;
         win.ResizeMode = ResizeMode.NoResize;
         win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
         win.Icon =...
         win.Show();
     }
}

Is there a way to do this in the Xaml with the dataTemplate?

I want a way to be able to change the style of the window created in WindowService in xaml not in the code. Not a global style but if for example I have viewModel1 and viewModel2 showWindow will be able to create two windows with different styles according to the viewModel passed to it

1

1 Answers

0
votes

To achieve this you can use the Windows ContentTemplateSelector property. First create a new DataTemplateSelector class. The purpose of this class is to identify the data template to use depending on the type of ViewModel that you passed in. In the SelectTemplate method, there's a parameter object item. There, you can get the Content of the Window, which in your case, in the service that you have, you're passing the view model to the window's content. Therefore, you will be able to get the view model from that object parameter.

 public class WindowTemplateSelector : DataTemplateSelector
  {
    public DataTemplate ViewModelTemplate1 { get; set; }
    public DataTemplate ViewModelTemplate2 { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
      if (item is ViewModel1)
        return ViewModelTemplate1;
      else
        return ViewModelTemplate2;
    }
  }

Then in the Application.Resources add two data templates and an instance of the template selector. You can see that in the local:WindowTemplateSelector, we specified which data template is for ViewModelTemplate1 and for ViewModelTemplate2.

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <DataTemplate x:Key="Template1">
      <Grid>
        <TextBlock Text="Hello World" />
      </Grid>
    </DataTemplate>
    <DataTemplate x:Key="Template2">
      <Grid>
        <TextBox Text="Hello World" />
      </Grid>
    </DataTemplate>
    <local:WindowTemplateSelector x:Key="windowTemplateSelector" 
                                  ViewModelTemplate1="{StaticResource Template1}"
                                  ViewModelTemplate2="{StaticResource Template2}"/>
  </Application.Resources>
</Application>

Then you need to pass the template selector to the service.

public class WindowService:IWindowService {
     public void ShowWindow(object viewModel, DataTemplateSelector templateSelector){
         var win = new Window {Content = viewModel};
         win.ContentTemplateSelector = templateSelector;
         win.Show();
     }
}

With this you can have multiple templates for different viewmodels for your window.