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

本文关键字:创建 代码 窗口 样式 添加 mvvm Xaml | 更新日期: 2023-09-27 18:10:58

这个问题是关于这个链接在MVVM WPF中打开新窗口

如果我有以下内容:

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

和我的app.xaml代码:

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

我不想在代码中添加如下样式:

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

是否有一种方法来做到这一点在Xaml与dataTemplate?

我想要一种方法,能够改变窗口的样式创建在窗口服务在xaml而不是在代码。不是全局样式但是如果我有viewModel1和viewModel2 showWindow将能够创建两个具有不同样式的窗口根据传递给它的viewModel

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

要做到这一点,你可以使用Windows的ContentTemplateSelector属性。首先创建一个新的DataTemplateSelector类。这个类的目的是根据传入的ViewModel类型确定要使用的数据模板。在SelectTemplate方法中,有一个参数对象item。在那里,你可以获得窗口的内容,在你的例子中,在你拥有的服务中,你将视图模型传递给窗口的内容。因此,您将能够从该对象参数中获得视图模型。

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

然后在应用程序中。资源添加了两个数据模板和一个模板选择器实例。可以看到,在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>

然后你需要将模板选择器传递给服务。

public class WindowService:IWindowService {
     public void ShowWindow(object viewModel, DataTemplateSelector templateSelector){
         var win = new Window {Content = viewModel};
         win.ContentTemplateSelector = templateSelector;
         win.Show();
     }
}
有了这个,你可以为你的窗口的不同视图模型拥有多个模板。