如何创建一个按钮,其中标题在viewmodel中基于布尔值更改但按钮基于样式资源?

时间:2017-01-25 16:21:36

标签: wpf mvvm wpf-style

也许我错过了一些明显的东西,但是我无法解决这个问题......我在App.xml中定义了一个按钮样式,它提供了一个" flat"看按钮:

<Style x:Key="FlatButton" TargetType="{x:Type Button}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Border x:Name="ButtonBorder" BorderThickness="2" BorderBrush="{DynamicResource color_Logo}" Padding="5,3,5,3" HorizontalAlignment="Stretch" Background="White">
          <TextBlock x:Name="ButtonText" FontSize="12" Foreground="{DynamicResource color_Logo}" HorizontalAlignment="Center" VerticalAlignment="Center"><ContentPresenter /></TextBlock>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="TextBlock.FontWeight" Value="Bold" />
          </Trigger>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="BorderBrush" Value="Gray" TargetName="ButtonBorder" />
            <Setter Property="Foreground" Value="Gray" TargetName="ButtonText" />
          </Trigger>
          <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="{DynamicResource color_LogoLight}" TargetName="ButtonBorder"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>          

在我的应用中完美运行。我现在需要创建一个具有此样式的按钮,但按钮的内容或标题会根据viewmodel中布尔值的状态而变化。我已经尝试了几次迭代,我最终得到了编译器的抱怨,即样式属性已经设置,或者我只是看到对象类型名称作为标题。

我想我可以在viewmodel中创建一个暴露正确标题的文本属性,但这似乎违反了MVVM中关注点的分离。虽然我知道如果我这样做不是一个可以逮捕的进攻,我的观点模型不应该关心UI呈现的方式,对吧?它只是暴露了对象的状态,UI决定如何呈现它。

另一种选择是根据viewmodel boolean创建两个按钮并隐藏不合适的按钮。这似乎更好地符合MVVM模式但我觉得我应该能够通过单个按钮上的触发器来实现这一点。

是否可以覆盖部分样式资源?

我现在正在使用双键解决方案,但我只是想知道自己错过了什么。

感谢。

Ĵ

2 个答案:

答案 0 :(得分:0)

  

是否可以覆盖部分样式资源?

没有。您确实可以将样式基于另一个样式并覆盖特定的setter,但不能“覆盖” ControlTemplate 的一部分。不幸的是,您必须(重新)定义整个模板:

WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?

答案 1 :(得分:0)

  

我想我可以在viewmodel中创建一个暴露正确标题的文本属性,但这似乎违反了MVVM中关注点的分离。

嗯,一点也不。名称View Model 意味着成为View的模型。当然这取决于少数设计选择,但在我看来,这并不违反MVVM。

除此之外,我会使用DataTrigger(在Style.Triggers中定义),您可以在给定布尔属性值的情况下设置特定的仅查看字符串。

而且,请不要使用双键解决方案, 更接近可逮捕的罪行; o)