#wpf #xaml
#wpf #xaml
Вопрос:
У меня есть кнопка, при наведении на нее курсора мыши поле вокруг нее уменьшается, и кнопка становится больше, а при нажатии на нее поле изменяется на предыдущее значение и становится меньше.
Но когда я нажимаю на кнопку и удерживаю ее, если я помещаю мышь «точно» на край кнопки, она непрерывно переключается между IsMouseOver
IsPressed
триггерами и, и это как бы конфликтует между ними и не знает, в каком состоянии она находится прямо сейчас, и заставляет кнопку увеличиваться, а затемпостоянно уменьшается, так как я могу это исправить?
Это код XAML
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="0,0,0,2"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="#4767CF"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Foreground" Value="#ADB5BD"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Margin" Value="6"/>
<Setter Property="Background" Value="#2F3439"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="310"
ShadowDepth="18" BlurRadius="30" Opacity="0.2"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Opacity="0"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Комментарии:
1. «это изменяет поле на предыдущее значение и становится меньше» — так что не делайте этого. Допускайте, чтобы на поле влияло только местоположение мыши (наведение курсора мыши), а не другой пользовательский ввод. Определение «нажатой» заключается в том, что мышь все еще находится над кнопкой после нажатия кнопки мыши. Ваш код намеренно приводит к тому, что этого не происходит. Это всего лишь вариант явно враждебного пользователю поведения при перемещении кнопки в совершенно другое место, когда пользователь пытается нажать на нее. Не пишите враждебный пользователю код, и проблема исчезнет.
2. Вы имеете в виду, что я даже не должен изменять размер кнопки?
3. Я не думаю, что существует фундаментальная проблема с увеличением размера при наведении курсора мыши на кнопку. Но тогда оставьте это так, пока мышь находится над кнопкой, даже если кнопка нажата. Тем не менее, да: вам, безусловно, следует подумать, разумно ли вообще изменять размер; в некоторых пользовательских интерфейсах такие вещи могут быть полезны, особенно когда кнопки на самом деле не похожи на кнопки, и вы хотите получить какую-то обратную связь типа «привет, пользователь, ты можешь нажать здесь». Но если это не применимо в вашей ситуации, возможно, полностью переосмыслите весь «волнистый пользовательский интерфейс».
Ответ №1:
Ниже приведено решение, которое использует поля для увеличения размера кнопки при наведении курсора мыши без мерцания. Однако гарантируется, что она будет работать только в том случае, если заданы ширина и высота кнопки. Если кнопка принимает свой размер из других элементов управления на экране, то мерцание может вернуться.
В приведенном ниже коде я использую поля границы, а не саму кнопку, для изменения размера, и я также использовал FallbackValue, чтобы сделать размер кнопки 50×100, если он явно не задан. В противном случае это почти тот же код, что и в вопросе.
XAML:
<Window x:Class="WpfApp12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp12"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<SolidColorBrush x:Key="BackgroundColor" Color="White"/>
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="0,0,0,2"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="#4767CF"/>
<Setter Property="Margin" Value="6"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Width" Value="{Binding Path=Width,FallbackValue=100}"/>
<Setter Property="Height" Value="{Binding Path=Height,FallbackValue=50}"/>
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Foreground" Value="#ADB5BD"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="MyBorder" Margin="2"
Padding="{TemplateBinding Padding}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Margin" Value="0" TargetName="MyBorder"/>
<Setter Property="Background" Value="#2F3439"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="310"
ShadowDepth="18" BlurRadius="30" Opacity="0.2"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="2" TargetName="MyBorder"/>
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Opacity="0"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Background="{StaticResource BackgroundColor}"></TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Background="{StaticResource BackgroundColor}" Width="100"></TextBlock>
<Button x:Name="MyButton" Height="100" Width="200" Style="{StaticResource MyButton}">Button</Button>
<TextBlock Background="{StaticResource BackgroundColor}" Width="700"></TextBlock>
</StackPanel>
<TextBlock Background="{StaticResource BackgroundColor}"></TextBlock>
</StackPanel>
</Window>
Альтернативное решение
В качестве альтернативы вы можете увеличить размер кнопки при наведении курсора мыши, используя свойство RenderTransform, которое является более стандартным способом решения проблемы в WPF. Проблема в том, что, похоже, содержимое кнопки размывается гораздо сильнее, чем просто установка поля:
<Window x:Class="WpfApp10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp10"
mc:Ignorable="d"
Title="MainWindow" Height="800" Width="800">
<Window.Resources>
<SolidColorBrush x:Key="BackgroundColor" Color="White"/>
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="0,0,0,2"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="#4767CF"/>
<Setter Property="Margin" Value="8"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Foreground" Value="#ADB5BD"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontSize" Value="16"/>
<!--<Setter Property="Margin" Value="6"/>-->
<Setter Property="Background" Value="#2F3439"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="310"
ShadowDepth="18" BlurRadius="30" Opacity="0.2"/>
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.03" ScaleY="1.03"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="FontSize" Value="14"/>
<!--<Setter Property="Margin" Value="8"/>-->
<Setter Property="Background" Value="#272C30"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Opacity="0"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Background="{StaticResource BackgroundColor}"></TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Background="{StaticResource BackgroundColor}" Width="100"></TextBlock>
<Button x:Name="MyButton" Height="100" Width="200" Style="{StaticResource MyButton}">Button</Button>
<TextBlock Background="{StaticResource BackgroundColor}" Width="700"></TextBlock>
</StackPanel>
<TextBlock Background="{StaticResource BackgroundColor}"></TextBlock>
</StackPanel>
</Window>