自定义按钮上的 XAML UWP 焦点背景
Posted
技术标签:
【中文标题】自定义按钮上的 XAML UWP 焦点背景【英文标题】:XAML UWP focus background on custom button 【发布时间】:2018-03-07 16:46:55 【问题描述】:在 XAML UWP 应用程序中,我有一个扩展 Button 的类。 我已经设置了背景 ImageBrush。
我的问题是,当我的按钮获得焦点或鼠标悬停事件时,我的按钮上会出现一个带有黑色边框的灰色矩形。
我已经尝试了 一大堆 解决方案,从更改前景到在各种事件(gotFocus
、mouseEntered
、mouseover
)上修改 FocusVisualPrimary/SecondaryBrush。
没有任何效果,我得到的最好结果是在mouseover
事件上设置button.Background = "originalBitmapImage"
(我创建了一个与原始背景具有相同图像路径的新ImageBrush,然后将其归因于BackGround),但是当鼠标悬停时图像全部闪烁触发(因为它每次都重新加载一个新图像)。
这是显示问题的图片(左:普通按钮,右:鼠标悬停的相同按钮):
我想在这两种情况下保持相同的图像,我有点不知所措。
public class MyButton : Button
private static string Image_path = "ms-appx:///assets/Button.png";
public MyButton()
ImageBrush brush = new ImageBrush()
ImageSource = new BitmapImage(new Uri(MyButton.Image_path))
;
this.Background = brush;
this.PointerEntered += a;
// This almost work, but the image is flickering when event is fired
private void a(object sender, PointerRoutedEventArgs e)
ImageBrush brush = new ImageBrush()
ImageSource = new BitmapImage(new Uri(MyButton.Image_path))
;
//this.Foreground = brush;
this.Background = brush;
【问题讨论】:
如果您只想停止闪烁,请将这些图像保存在一些外部字段中。如果你想防止这种奇怪的行为,你可以创建模板,或者更容易使用 ContentControl 并将图像设置为内容,或者使用它的背景属性设置边框 【参考方案1】:我们可以复制Button
的默认样式,然后我们可以在Template
中编辑VisualState
的PointerOver
。
从默认样式开始,它将ButtonBackgroundPointerOver
ThemeResource 设置为PointerOver
VisualState 中Button 的Background
。所以我们可以在页面资源中定义ButtonBackgroundPointerOver
,而不需要修改Button
的样式。
例如:
<Page.Resources>
<StaticResource x:Key="ButtonBackground" ResourceKey="MyMyImageBrush" />
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="MyMyImageBrush" />
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
<ImageBrush x:Key="MyMyImageBrush" ImageSource="ms-appx:///assets/Button.png" />
</Page.Resources>
【讨论】:
谢谢,我会在短时间内测试这个解决方案。万一,有没有办法在代码后面做到这一点?我的按钮此时是一个类,而不是 XAML 元素。 这是我目前得到的最佳解决方案,但这会修改页面上的所有按钮。问题是我可以有不止一种类型的按钮:所以我需要能够为不同类型的按钮设置不同的背景(即在我的情况下是不同的图像)。如果有一个解决方案可以直接在我的不同按钮类中的代码上实现,那将非常酷。谢谢【参考方案2】:最后我找到了一个解决方案:我为项目的每个页面添加了 5 种类型的按钮样式。这不是一个很好的解决方案,因为按钮是从 c# 类(后面的代码)创建的,以便分解代码,并且所有样式都添加了 500+ 代码行,以便在鼠标悬停时进行简单的图像修改......
我使用了这种样式:
'
<Style TargetType="local:MyButton">
<!--<Setter Property="Background" Value="ThemeResource SystemControlBackgroundBaseLowBrush" />
<Setter Property="Foreground" Value="ThemeResource SystemControlForegroundBaseHighBrush"/>
<Setter Property="BorderBrush" Value="ThemeResource SystemControlForegroundTransparentBrush" />
<Setter Property="BorderThickness" Value="ThemeResource ButtonBorderThemeThickness" />-->
<Setter Property="Padding" Value="8,4,8,4" />
<!--<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="ThemeResource ContentControlThemeFontFamily" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="ThemeResource ControlContentThemeFontSize" />-->
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyButton">
<Grid x:Name="RootGrid" Background="TemplateBinding Background">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlHighlightBaseMediumLowBrush" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlHighlightBaseHighBrush" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlBackgroundBaseMediumLowBrush" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlHighlightTransparentBrush" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlHighlightBaseHighBrush" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlBackgroundBaseLowBrush" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlDisabledBaseMediumLowBrush" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="ThemeResource SystemControlDisabledTransparentBrush" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="TemplateBinding BorderBrush"
BorderThickness="TemplateBinding BorderThickness"
Content="TemplateBinding Content"
ContentTransitions="TemplateBinding ContentTransitions"
ContentTemplate="TemplateBinding ContentTemplate"
Padding="TemplateBinding Padding"
HorizontalContentAlignment="TemplateBinding HorizontalContentAlignment"
VerticalContentAlignment="TemplateBinding VerticalContentAlignment"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>'
【讨论】:
以上是关于自定义按钮上的 XAML UWP 焦点背景的主要内容,如果未能解决你的问题,请参考以下文章