在WPF中的视图模型上应用样板样式

本文关键字:应用 样式 模型 WPF 视图 | 更新日期: 2023-09-27 18:29:29

我正在开发一个WPF应用程序,该应用程序包含一个设计器,它显示不同元素(形状)的垂直ListView。

我为设计师创建了一个视图模型,并为每个形状创建了视图模型。为了将设计器的视图绑定到视图模型,我使用了"DataContext"属性。

但我的问题是,我在一个XAML文件中定义了形状的所有视图样式(模板),我不知道如何将它们绑定到它们的视图模型!!

我在网上找到了这个:

var resourceDictionary = new ResourceDictionary()
        {
            Source = new Uri("SymbolTemplates.xaml", UriKind.Relative)
        };
Style template = resourceDictionary["SMS"] as Style;

所以我把它放在我的视图模型构造函数中,但我该怎么处理这个假"模板"呢??

让事情变得更清楚:

1) 这是我的设计师观点:

<Grid SizeChanged="Grid_SizeChanged"> 
  <ListView x:Name="ShapesViewer" BorderThickness="0" Background="YellowGreen" ItemsSource="{Binding ChildrenList}"> 
    <ListView.LayoutTransform> 
       <RotateTransform Angle="{Binding Orientation}" />
    </ListView.LayoutTransform> 
  </ListView> 
</Grid>

"ChildrenList"包含我的形状视图模型的列表。

2) 这是我的"SymbolTemplates.xaml",我在其中定义了我所有的形状样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:mvvm="clr-namespace:ViewModel;assembly=ViewModel">
<Style x:Key="CircleStyle"
       TargetType="ListViewItem">
    <Setter Property="Visibility" Value="Visible"/>
            <!--Value="{Binding IsExpanded, Mode=TwoWay}" />-->
    <Setter Property="Width"
            Value="70" />
    <Setter Property="Height"
            Value="32" />
    <Setter Property="Margin"
            Value="0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <Grid Height="32"
                      Width="50"
                      Background="Transparent">
                    <Grid.HorizontalAlignment>
                        <MultiBinding  Converter="{StaticResource EvenToHorizontalAlignementMultiConverter}">
                            <Binding Path="Position" />
                            <Binding Path="RenderCenter" />
                        </MultiBinding>
                    </Grid.HorizontalAlignment>
                    <Ellipse Width="30"
                             Height="30"
                             HorizontalAlignment="Center"
                             VerticalAlignment="Center"
                             StrokeThickness="3" 
                             Fill="WhiteSmoke">
                    </Ellipse>
                     <ItemsPresenter Grid.Row="1"
                                    Visibility="{Binding IsExpanded, Converter= {StaticResource VisibilityOfBool} }" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
...

所以,我定义了这个样式(对于圆),我还有一个对象CircleVM(视图模型)。

我的问题是:在ListView(名为"ShapesViewer")中定义的"ChildrenList"中添加此"CircleStyle"时,我应该如何将其分配给我的"CircleVM"

在WPF中的视图模型上应用样板样式

要解决您用粗体写的声明:

你的Style,而不是你说的"对于一个圆圈"。。。它用于CCD_ 2。不能将具有TargetType="ListViewItem"Style设置为UserControl

与其这样做,不如为每个视图定义一个DataTemplate,定义希望每个视图模型中的数据如何显示。。。例如(假设Circle类中有一个公共Name属性):

<DataTemplate DataType="{x:Type YourDataTypesNamespace:Circle}">
    <Grid Height="32" Width="50" Background="Transparent">
        <Ellipse Width="30" Height="30" HorizontalAlignment="Center" 
VerticalAlignment="Center" StrokeThickness="3" Fill="WhiteSmoke" />
        <TextBlock Text="{Binding Name}" />
    </Grid>
</DataTemplate>

更新结束>>

首先,您可以从Resources部分加载DataTemplate,如下所示:

ComponentResourceKey templateKey = new ComponentResourceKey(typeof(YourViewModel), 
"YourViewModelDataTemplate");
DataTemplate dataTemplate = (DataTemplate)this.TryFindResource(templateKey);

然后,您可以将DataTemplate与特定的ContentControl连接起来,如下所示:

contentControl.ContentTemplate = dataTemplate;

这假设您有一个名为contentControlContentControl

或者,您可以创建一个简单的DataTemplate,以编程方式将每个视图与其相关的视图模型连接起来,如下所示:

DataTemplate dataTemplate = new DataTemplate();
dataTemplate.DataType = typeof(YourViewModel);
FrameworkElementFactory view = new FrameworkElementFactory(typeof(YourView));
dataTemplate.VisualTree = view;

更新>>>

但是,如果每个视图模型都有一个视图(UserControl),那么有一种更简单的方法来连接它们。。。将这些添加到App.xaml:中

<DataTemplate DataType="{x:Type ViewModels:CircleViewModel}">
    <Views:CircleView />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:SquareViewModel}">
    <Views:SquareView />
</DataTemplate>