简体   繁体   English

如何在Xaml中为使用mvvm代码创建的窗口添加样式?

[英]How to add style in Xaml for a Window created from code with mvvm?

This question is in reference to this link Opening new window in MVVM WPF . 此问题参考此链接在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: 和我的app.xaml代码:

<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? 有没有办法在Xaml中使用dataTemplate做到这一点?

I want a way to be able to change the style of the window created in WindowService in xaml not in the code. 我想要一种方法,能够在xaml中而不是在代码中更改在WindowService中创建的窗口的样式。 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 不是全局样式,但是例如,如果我有viewModel1和viewModel2,则showWindow将能够根据传递给它的viewModel创建两个具有不同样式的窗口

To achieve this you can use the Windows ContentTemplateSelector property. 为此,您可以使用Windows ContentTemplateSelector属性。 First create a new DataTemplateSelector class. 首先创建一个新的DataTemplateSelector类。 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. 此类的目的是根据传入的ViewModel的类型来标识要使用的数据模板。在SelectTemplate方法中,有一个参数对象项。 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. 然后在Application.Resources中添加两个数据模板和一个模板选择器实例。 You can see that in the local:WindowTemplateSelector , we specified which data template is for ViewModelTemplate1 and for ViewModelTemplate2 . 您可以在local:WindowTemplateSelector ,我们指定了哪个数据模板用于ViewModelTemplate1ViewModelTemplate2

<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. 有了它,您可以为窗口的不同视图模型提供多个模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM