开发者

WPF: Binding commands in styles and/or data templates (MVVM)?

Here's the very quick and simplified explanation of my situation. I have defined a style for Hyperlink controls and they have Command property binded to the command defined in a ViewModel class (simplified):

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

Next, I created a content control in the window I am designing. It has a data template defined, written in the window resources. Inside that data template, I added some hyperlinks and I set those hyperlinks to use the previously defined style.

The window looks like this (simplified):

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

The data template looks like this (simplified):

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

The binding to the OpenHyperlinkCommand in the style doesn't work because the ViewModel of the window bound to it contains this command, but the Da开发者_开发问答taTemplate is bound to the MyType objects, which do not contain this command (nor should).

How should I make this binding work? Two questions:

  1. Here's my proposal: I named my window x:Name="myWindow", and changed the binding of the command inside the style to this:

    <Setter Property="Command" Value="{Binding ElementName=myWindow Path=DataContext.OpenHyperlinkCommand}" />
    

    This works, but it looks so dirty. Am I doing this wrong? Is there a better way, more MVVM-like? This is fragile because I am setting specific element name inside a style!

  2. Is it a good practice to write the command bindings inside of a style in the first place? If not, what is the alternative? What if I developed a complex UserControl, how would I set commands to components somewhere deep inside its logical tree?

Thanks for all the help!


  1. An alternative syntax would use RelativeSource

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

  2. I don't see anything wrong with writing command bindings in a style

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜