WPF:样式和/或数据模板(MVVM)中的绑定命令?

时间:2011-04-12 22:45:59

标签: wpf mvvm binding styles

这是我的情况的快速和简化的解释。我为Hyperlink控件定义了一个样式,它们的Command属性绑定到ViewModel类中定义的命令(简化):

<Window.Resources>
  ...
  <Style x:Key="hyperlinkStyle" TargetType="Hyperlink">
    ...
    <Setter Property="Command" Value="{Binding Path=OpenHyperlinkCommand}" />
    ...
  </Style>
  ...
</Window.Resources>

接下来,我在我正在设计的窗口中创建了一个内容控件。它有一个定义的数据模板,写在窗口资源中。在该数据模板中,我添加了一些超链接,并设置了这些超链接以使用先前定义的样式。

窗口看起来像这样(简化):

<Window>
  ...
  <ContentControl 
      ...
      ContentTemplate="{StaticResource myDataTemplate}" />
  ...
</Window>

数据模板如下所示(简化):

<Window.Resources>
  ...
  <DataTemplate x:Key="myDataTemplate DataType="{x:Type my:MyType}">
    ...
    <TextBlock>
      <Hyperlink 
          Style="{StaticResource hyperlinkStyle}" 
          CommandParameter="{Binding Path=Uri1}">
        <TextBlock Text="{Binding Path=Uri1}" />
      </Hyperlink>
    </TextBlock>
    ...
    <TextBlock>
      <Hyperlink 
          Style="{StaticResource hyperlinkStyle}" 
          CommandParameter="{Binding Path=Uri2}">
        <TextBlock Text="{Binding Path=Uri2}" />
      </Hyperlink>
    </TextBlock>
    ...
  </DataTemplate>
  ...
</Window.Resources>

对样式中OpenHyperlinkCommand的绑定不起作用,因为绑定到它的窗口的ViewModel包含此命令,但DataTemplate绑定到{{1}对象,不包含此命令(也不应该)。

我应该如何使这个绑定工作?两个问题:

  1. 这是我的建议:我将我的窗口命名为MyType,并更改了绑定 样式内的命令:

    x:Name="myWindow"

    这样可行,但看起来很脏。我做错了吗?是否有更好的方式,更多 MVVM样?这很脆弱,因为我在样式中设置了特定的元素名称!

  2. 在第一个样式中编写命令绑定是一个好习惯 地点?如果没有,有什么替代方案?如果我开发了一个复杂的<Setter Property="Command" Value="{Binding ElementName=myWindow Path=DataContext.OpenHyperlinkCommand}" /> , 如何在逻辑树内部的某个位置设置命令?

  3. 感谢您的帮助!

1 个答案:

答案 0 :(得分:19)

  1. 替代语法将使用RelativeSource

    <Setter Property="Command" Value="{Binding DataContext.OpenHyperlinkCommand, RelativeSource={Relative Source AncestorType={x:Type Window}}}">

  2. 我没有看到以样式编写命令绑定有什么问题