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

时间:2015-09-03 15:05:17

标签: c# wpf xaml mvvm

此问题仅参考此链接Opening new window in 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中而不是在代码中更改WindowService中创建的窗口样式的方法。不是全局样式但是例如我有viewModel1和viewModel2 showWindow将能够根据传递给它的viewModel创建两个具有不同样式的窗口

1 个答案:

答案 0 :(得分:0)

要实现此目的,您可以使用Windows ContentTemplateSelector属性。首先创建一个新的DataTemplateSelector类。此类的目的是根据您传入的ViewModel类型识别要使用的数据模板。在SelectTemplate方法中,有一个参数对象项。在那里,您可以获得窗口的内容,在您的情况下,在您拥有的服务中,您将视图模型传递到窗口的内容。因此,您将能够从该对象参数获取视图模型。

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

然后在Application.Resources中添加两个数据模板和一个模板选择器实例。您可以在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();
     }
}

使用此功能,您可以为窗口设置多个不同视图模型的模板。