Круглая кнопка WPF

#c# #wpf #xaml #mvvm-light

Вопрос:

Я пытаюсь создать круглую кнопку с рамкой, отображаемой при наведении курсора, и цветом, привязанным к объекту. Я пытался сделать это, но когда цвет кнопки отличается от прозрачного, я не могу нажать на нее. Не могли бы вы мне помочь, пожалуйста ? Я новичок в wpf и не все понимаю в этом.

  <Page.Resources>

    <DataTemplate x:Key="Stone">
        <StackPanel DataContext="{Binding}">

            <Border CornerRadius="15" Height="30" Width="30" Margin="0"  >
                <Button Content="{Binding}" Tag="{Binding Name}" Height="30" Width="30" Margin="0" Click="Button_Click" Background="Transparent" BorderThickness="0">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="Button">
                                        <Grid Background="{TemplateBinding Background}">
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Normal"/>
                                                    <VisualState x:Name="MouseOver"/>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Button.Style>
                </Button>
                <Border.Style>
                    <Style TargetType="Border">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding StrColor}" Value="black">
                                <Setter Property="Background" Value="Black"></Setter>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding StrColor}" Value="white">
                                <Setter Property="Background" Value="White"></Setter>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding StrColor}" Value="none">
                                <Setter Property="Background" Value="Transparent"></Setter>
                            </DataTrigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                     <Setter Property="BorderBrush" Value="Gray"/>
                                <Setter Property="BorderThickness" Value="3"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="False">
                                <Setter Property="BorderBrush" Value="Transparent"/>
                                <Setter Property="BorderThickness" Value="0"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>             

        </StackPanel>
    </DataTemplate>


    <DataTemplate x:Key="Goban">
        <ItemsControl ItemsSource="{Binding }" ItemTemplate="{DynamicResource Stone}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>
 

Ресурсы>

 <StackPanel Name="Goban">
    <ItemsControl  Height="570" Margin="20" x:Name="LstPlateau" ItemsSource="{Binding LstPlateau, Mode=Default}" ItemTemplate="{DynamicResource Goban}">
        <ItemsControl.Background>

            <ImageBrush ImageSource="../Pictures/goban19.png" Stretch="Fill" />
        </ItemsControl.Background>
    </ItemsControl>
</StackPanel>
    
 

Для получения более подробной информации я использую mvvm light, и когда я нажимаю прозрачную кнопку, срабатывает команда, но она не имеет другого цвета (точка останова в команде не достигнута).
Спасибо вам за вашу помощь 🙂

Комментарии:

1. Почему вы пишете «круглая кнопка», но показываете шаблон прямоугольной кнопки и несвязанный стиль, содержащий только триггеры?

2. Я попытался создать круглую кнопку, используя рамку шириной и высотой 30 и радиусом закругления 15. Это делает прямоугольник только с закругленными углами, то есть круг. Кнопка находится внутри границы и «невидима».

3. @rodolphejamin: Почему вы могли бы нажать на кнопку, когда Background Border она есть Transparent , но не когда она установлена на какую-то другую Brush ? В этом нет никакого смысла. Как воспроизвести вашу проблему?

Ответ №1:

Кнопка находится внутри границы и «невидима».

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

Вот пример шаблона ПОЛНОЙ круглой кнопки. Запишите его в словарь ресурсов и используйте в своей кнопке.

Я не устанавливал привязки цветов, потому что не понял из вашего кода, где они используются.

         <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
        <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
        <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
        <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
       <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="ButtonRoundStyle" TargetType="{x:Type Button}">
            <Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
            <Setter Property="Background" Value="{DynamicResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Ellipse x:Name="ellipse"
                                     Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{Binding BorderThickness.Left, RelativeSource={RelativeSource AncestorType=Button}}"
                                     Fill="{TemplateBinding Background}" SnapsToDevicePixels="true">
                            </Ellipse>
                            <ContentPresenter x:Name="contentPresenter" Focusable="False"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsDefaulted" Value="true">
                                <Setter Property="Stroke" TargetName="ellipse" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Fill" TargetName="ellipse" Value="{DynamicResource Button.MouseOver.Background}"/>
                                <Setter Property="Stroke" TargetName="ellipse" Value="{DynamicResource Button.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter Property="Fill" TargetName="ellipse" Value="{DynamicResource Button.Pressed.Background}"/>
                                <Setter Property="Stroke" TargetName="ellipse" Value="{DynamicResource Button.Pressed.Border}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Fill" TargetName="ellipse" Value="{DynamicResource Button.Disabled.Background}"/>
                                <Setter Property="Stroke" TargetName="ellipse" Value="{DynamicResource Button.Disabled.Border}"/>
                                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{DynamicResource Button.Disabled.Foreground}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
 

Все ключи получены с помощью DynamicResource.
Поэтому они могут быть переопределены в том месте, где применяется шаблон.

Я отредактировал вопрос, в своем проекте я стараюсь …

После дополнения вопроса полным кодом XAML, если я правильно его понял, шаблон, который я показал, применяется следующим образом:

     <Button  Content="{Binding}" Tag="{Binding Name}"
                Height="130" Width="130" Margin="0"
                Click="Button_Click">
        <Button.Resources>
            <SolidColorBrush x:Key="Button.MouseOver.Border" Color="Gray"/>
        </Button.Resources>
        <Button.Style>
            <Style TargetType="Button" BasedOn="{StaticResource ButtonRoundStyle}">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding StrColor}" Value="black">
                        <Setter Property="Background" Value="Black"></Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding StrColor}" Value="white">
                        <Setter Property="Background" Value="White"></Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding StrColor}" Value="none">
                        <Setter Property="Background" Value="Transparent"></Setter>
                    </DataTrigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderThickness" Value="3"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
 

Комментарии:

1. Спасибо за вашу помощь, я ее переработаю 🙂

2. Насколько я понимаю, вам нужно только настроить триггеры данных для переключения фона в кнопке в месте ее объявления. Обычные триггеры для IsMouseOver — удалить.

3. Я также уточняю, возможно, вы этого не знаете. Transparent устанавливает кисть в положение прозрачной. Прозрачность также будет , если установлено значение null , то есть, если нет кисти. Но если кисти нет, то объекты, для которых кисти нет, будут «прозрачными» для щелчков мыши.

4. Итак, если я помещу кнопку в рамку , фон рамки будет над ней и заблокирует нажатие ?

5. Окончательное расположение элементов мне не ясно из ваших объяснений. Будет лучше, если вы покажете это в XAML.