Как создать кнопку, в которой заголовок изменяется в зависимости от логического значения в 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 без переопределения всего стиля?