Как создать кнопку, в которой заголовок изменяется в зависимости от логического значения в viewmodel, но кнопка основана на ресурсе стиля?

Возможно, я упускаю что-то очевидное, но я не могу понять это... У меня есть стиль кнопки, определенный в App.xml, который представляет "плоскую" кнопку:

<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, которое выставляет правильную подпись, но это, кажется, нарушает разделение интересов в MVVM. Хотя я знаю, что если я это сделаю, это не преступление, способное арестовать, моя модель представления не должна заботиться о том, как пользовательский интерфейс представляет что-то, верно? Он просто показывает состояние объекта, и пользовательский интерфейс принимает решение о том, как его представить.

Другой вариант - создать две кнопки и скрыть ту, которая не подходит, на основе логического значения viewmodel. Похоже, это немного лучше соответствует шаблону MVVM, но я чувствую, что могу сделать это с помощью триггера на одной кнопке.

Можно ли переопределить часть ресурса стиля?

Сейчас я использую решение с двумя кнопками, но я просто хотел бы знать, что мне не хватает.

Благодарю.

J

2 ответа

Я полагаю, я мог бы создать текстовое свойство в viewmodel, которое выставляет правильную подпись, но это, кажется, нарушает разделение интересов в MVVM.

Ну, совсем нет. Само название View Model подразумевает быть моделью для View. Конечно, это зависит от нескольких вариантов дизайна, но, на мой взгляд, это не является нарушением MVVM.

Кроме того, я бы пошел с DataTrigger (определенный в Style.Triggers), где вы можете установить конкретные строки только для просмотра, учитывая значение вашего логического свойства.

И, пожалуйста, не используйте двухкнопочное решение, которое ближе к аресту;o)

Можно ли переопределить часть ресурса стиля?

Нет. Вы действительно можете основывать Стиль на другом Стиле и переопределять специфические сеттеры, но вы не можете "переопределить" только часть ControlTemplate. К сожалению, вы должны (пере) определить весь шаблон в целом:

WPF: есть ли способ переопределить часть ControlTemplate без переопределения всего стиля?

Другие вопросы по тегам