#c# #wpf
#c# #wpf
Вопрос:
Я разрабатываю приложение с использованием C # и WPF в стиле MVVM. У меня есть кнопка с пользовательским стилем, поэтому при фокусировке она отображает черную рамку. Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть требование, чтобы кнопка была сфокусирована при загрузке формы, но когда я делаю это, она не применяет стиль.
Я пробовал использовать FocusManager.FocusedElement="{Binding ElementName=Button}"
в представлении Button.focus()
и Keyboard.Focus(Button)
в коде как в событии загрузки формы, так и в событии загрузки кнопки, но похоже, что он просто фокусирует кнопку без применения стиля.
Стиль кнопки:
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource SquareButtonStyle}"
x:Key="CustomNegativeButtonStyle">
<Setter Property="BorderBrush" Value="{DynamicResource AccentColorBrush}"/>
<Setter Property="controls:ControlsHelper.ContentCharacterCasing" Value="Normal"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsKeyboardFocused" Value="True"/>
<Condition Property="IsMouseOver" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="BorderThickness" Value="2.25"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlackBrush}"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type customControls:SquareRadisButton}"
BasedOn="{StaticResource CustomAccentedSquareButtonStyle}" >
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="15 5"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type customControls:SquareRadisButton}">
<customControls:SquareRadisButton Style="{StaticResource CustomAccentedSquareButtonStyle}"
Command="{TemplateBinding Command}"
CommandParameter="{TemplateBinding CommandParameter}"
Padding="{TemplateBinding Padding}"
x:Name="SquareRadisButton">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding Text}"
Margin="0 0 5 0"
x:Name="ButtonText"/>
<TextBlock Text="{TemplateBinding IconGlyph}"
FontFamily="{DynamicResource FontAwesome}"
VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
x:Name="ButtonIcon"/>
</StackPanel>
</customControls:SquareRadisButton>
<ControlTemplate.Triggers>
<Trigger Property="IconGlyph" Value="{x:Null}">
<Setter TargetName="ButtonText" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter TargetName="ButtonText" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="IsNegativeButton" Value="True">
<Setter TargetName="SquareRadisButton" Property="Style" Value="{StaticResource CustomNegativeButtonStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Код позади:
public partial class OkCancelDialogView
{
public OkCancelDialogView()
{
InitializeComponent();
}
private void OkCancelDialogView_OnLoaded(object sender, RoutedEventArgs e)
{
}
private void CancelButton_OnLoaded(object sender, RoutedEventArgs e)
{
CancelButton.Focus();
}
}
Вид:
<dialog:BaseMetroDialog x:Class="Wris.Modules.Referral.UI.View.Dialog.OkCancelDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
xmlns:controls="clr-namespace:Wris.Modules.Referral.UI.Controls"
Loaded="OkCancelDialogView_OnLoaded"
Title="{Binding DialogOptions.Title}">
<dialog:BaseMetroDialog.InputBindings>
<KeyBinding Key="Escape" Command="{Binding CancelCommand}"/>
</dialog:BaseMetroDialog.InputBindings>
<Grid Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DialogOptions.Message}"
FontSize="15"
VerticalAlignment="Center"/>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Grid.Row="2" Grid.Column="1"
Margin="10">
<controls:SquareRadisButton Text="{Binding DialogOptions.AffirmativeButtonText}"
Command="{Binding OkCommand}"
TabIndex="1"
MinWidth="80"/>
<controls:SquareRadisButton Command="{Binding CancelCommand}"
IsNegativeButton="True"
TabIndex="0"
Text="{Binding DialogOptions.NegativeButtonText}"
Visibility="{Binding DialogOptions.NegativeButtonVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
MinWidth="80"
x:Name="CancelButton"
Loaded="CancelButton_OnLoaded"/>
</StackPanel>
</Grid>
</dialog:BaseMetroDialog>
Комментарии:
1. Из того, что я вижу
CustomNegativeButtonStyle
, на самом деле это нигде не применяется. Либо назначьте ее своим кнопкам с помощьюStyle
свойства, либо сделайте ее неявным стилем, опустив ключ, если вы хотите применить стиль ко всем кнопкам в области видимости.2. Извините за это, у меня есть родительский стиль, который устанавливает для стиля значение CustomNegativeButton, если
"IsNegativeButton="True""
подобное свойство указано выше. Я отредактирую вопрос, чтобы включить этот стиль3. @Ben:
Focus()
Возвращает ли методtrue
? Вы пробовали использовать этотKeyboard.Focus
метод? Существует разница между логическим и клавиатурным фокусом.4. Да, он возвращает true, похоже, что кнопка находится в фокусе, но она не применяет стиль, пока пользователь не нажмет на нее или не добавит к ней вкладки. Я также пробовал использовать keyboard.focus, но я не вижу никакой разницы
5. Действительно ли этот код выполняется так, как вы его показали? Похоже, вы определяете шаблон элемента управления для SquareRadisButton, который включает в себя сам SquareRadisButton. WPF предсказуемо выдает во время выполнения для меня, говоря, что он не может определить элемент управления в терминах самого себя.
Ответ №1:
В вашем Button
стиле ваш триггер может быть упрощен для использования IsFocused
свойства:
<Trigger Property="IsFocused" Value="True">
...
</Trigger>
Поскольку это диалоговое окно, скорее всего, вам не нужно устанавливать Focus
значение Button
, но нужно установить его в качестве кнопки по умолчанию. Это заставит ее щелкать, когда пользователь нажимает Enter
клавишу.
Вы можете сделать это, установив IsDefault
свойство.
В вашем стиле вы также можете добавить Trigger
для IsDefault
свойства и придать ему границу, аналогичную вашему состоянию фокусировки.
<Trigger Property="IsDefault" Value="True">
...
</Trigger>
Комментарии:
1. Я не совсем уверен, что происходит со стилем при первой загрузке окна. Я только что опробовал это решение, и кнопка фокусируется, но она по-прежнему не применяет стиль
Ответ №2:
После изучения стилей, примененных к кнопке, я считаю, что проблема связана с тем, что к кнопке применяются 2 стиля. Похоже, что CustomNegativeButtonStyle не применяется до тех пор, пока не будет загружено окно, поэтому, как только я переместил триггеры в исходный стиль, кнопка стала ориентироваться на загрузку формы.
<Style TargetType="{x:Type customControls:SquareRadisButton}"
BasedOn="{StaticResource CustomAccentedSquareButtonStyle}" >
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="15 5"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type customControls:SquareRadisButton}">
<customControls:SquareRadisButton Style="{StaticResource CustomAccentedSquareButtonStyle}"
Command="{TemplateBinding Command}"
CommandParameter="{TemplateBinding CommandParameter}"
Padding="{TemplateBinding Padding}"
x:Name="SquareRadisButton">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding Text}"
Margin="0 0 5 0"
x:Name="ButtonText"/>
<TextBlock Text="{TemplateBinding IconGlyph}"
FontFamily="{DynamicResource FontAwesome}"
VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
x:Name="ButtonIcon"/>
</StackPanel>
</customControls:SquareRadisButton>
<ControlTemplate.Triggers>
<Trigger Property="IconGlyph" Value="{x:Null}">
<Setter TargetName="ButtonText" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter TargetName="ButtonText" Property="Margin" Value="0"/>
</Trigger>
<Trigger Property="IsNegativeButton" Value="True">
<Setter TargetName="SquareRadisButton" Property="Style" Value="{StaticResource CustomNegativeButtonStyle}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsKeyboardFocused" Value="True"/>
<Condition Property="IsMouseOver" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="SquareRadisButton" Property="BorderThickness" Value="2.25"/>
<Setter TargetName="SquareRadisButton" Property="BorderBrush" Value="{DynamicResource BlackBrush}"/>
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>