Кнопка не устанавливает тему при выборе в коде позади

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