使用模板控制自定义按钮的文本格式、换行符和颜色
Controlling text formatting, linebreaks, and colors of custom button with template
有人要求我构建一个相对简单的应用程序启动器程序(以替换旧的基于 DOS 的菜单系统)。我在 WPF 中构建了应用程序,并创建了一个自定义的 class 派生自名为“ApplicationLauncherButton”的按钮。
我希望所有按钮都具有相同的“外观和感觉”,因此我决定它们的样式都相同。因此,我决定用我要创建的模板替换控件模板。为了让我的主要 window XAML 尽可能干净,我创建了一个单独的资源字典文件来保存模板并在 app.xaml.
中引用它
这相当有效。但是,按钮上的某些文本很长,我想控制换行符出现的位置。通过将按钮文本包装在 TextBlock 中并在我需要的位置插入标签,可以相对轻松地完成此操作。不幸的是,这有一个副作用:不再应用我希望在鼠标悬停事件上发生的文本颜色更改。当按钮文本未包含在 TextBlock 中时,鼠标悬停格式会按预期工作,但我无法控制换行符出现的位置。
我花了几个小时试图弄清楚如何让它工作,但没有任何运气。我只使用 WPF 几个星期,所以可能有更简单的方法来完成我想做的事情。欢迎任何建议。
App.xaml
<Application x:Class="WPF1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Default\Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="WPF1.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:WPF1"
mc:Ignorable="d"
Title="Application Launcher" Height="787" Width="728"
Background="{StaticResource Default.DarkGreenBrush}" SizeChanged="Window_SizeChanged" WindowStartupLocation="CenterScreen">
<StackPanel Margin="5">
<GroupBox Header="Design Programs" Margin="5" Foreground="White" FontSize="11" FontWeight="Bold">
<WrapPanel>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp1.exe"
Click="ApplicationLauncherButton_Click">
Designer Application 1
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp2.exe"
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 2
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp3.exe"
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 3
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp4.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 4
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp5.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 5
</TextBlock>
</local:ApplicationLauncherButton>
</WrapPanel>
</GroupBox>
<GroupBox Header="Utility Programs" Margin="5" Foreground="White" FontSize="11" FontWeight="Bold">
<WrapPanel>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp1.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 1</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp2.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 2</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp3.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 3</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp4.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 4</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp5.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 5</TextBlock>
</local:ApplicationLauncherButton>
</WrapPanel>
</GroupBox>
</StackPanel>
</Window>
Button.xaml(在项目的\Themes\Default文件夹中)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF1">
<!-- Colors -->
<Color x:Key="Default.LightGreen">#509248</Color>
<Color x:Key="Default.DarkGreen">#014419</Color>
<Color x:Key="Button.Static.Background.Color">#FFDDDDDD</Color>
<Color x:Key="Button.Static.Border.Color">#FF707070</Color>
<Color x:Key="Button.Static.Foreground.Color">#FFFFFF</Color>
<Color x:Key="Button.MouseOver.Background.Color">#90D288</Color>
<Color x:Key="Button.MouseOver.Border.Color">#FF707070</Color>
<Color x:Key="Button.MouseOver.Foreground.Color">#EEEE00</Color>
<Color x:Key="Button.Pressed.Background.Color">#307228</Color>
<Color x:Key="Button.Pressed.Border.Color">#FF505050</Color>
<Color x:Key="Button.Disabled.Background.Color">#FFF4F4F4</Color>
<Color x:Key="Button.Disabled.Border.Color">#FFADB2B5</Color>
<Color x:Key="Button.Disabled.Foreground.Color">#FF838383</Color>
<!-- Brushes -->
<SolidColorBrush x:Key="Default.LightGreenBrush" Color="{StaticResource Default.LightGreen}"/>
<SolidColorBrush x:Key="Default.DarkGreenBrush" Color="{StaticResource Default.DarkGreen}"/>
<SolidColorBrush x:Key="Button.Static.Background.Brush" Color="{StaticResource Default.LightGreen}" />
<SolidColorBrush x:Key="Button.Static.Border.Brush" Color="{StaticResource Button.Static.Border.Color}"/>
<SolidColorBrush x:Key="Button.Static.Foreground.Brush" Color="{StaticResource Button.Static.Foreground.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Background.Brush" Color="{StaticResource Button.MouseOver.Background.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Border.Brush" Color="{StaticResource Button.MouseOver.Border.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Foreground.Brush" Color="{StaticResource Button.MouseOver.Foreground.Color}"/>
<SolidColorBrush x:Key="Button.Pressed.Background.Brush" Color="{StaticResource Button.Pressed.Background.Color}"/>
<SolidColorBrush x:Key="Button.Pressed.Border.Brush" Color="{StaticResource Button.Pressed.Border.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Background.Brush" Color="{StaticResource Button.Disabled.Background.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Border.Brush" Color="{StaticResource Button.Disabled.Border.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground.Brush" Color="{StaticResource Button.Disabled.Foreground.Color}"/>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ApplicationLauncherButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background.Brush}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border.Brush}"/>
<Setter Property="Foreground" Value="{StaticResource Button.Static.Foreground.Brush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Width" Value="125"/>
<Setter Property="Height" Value="125"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="control" TargetType="{x:Type local:ApplicationLauncherButton}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<TextBlock x:Name="textBlock" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter x:Name="contentPresenter" Focusable="False" RecognizesAccessKey="True" Visibility="Visible"/>
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.MouseOver.Foreground.Brush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.MouseOver.Foreground.Brush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground.Brush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
附带说明一下,我按原样构建 window 的部分原因是我打算将应用程序信息移动到数据源,根据数据动态创建按钮和组.这将允许我添加/删除应用程序而无需修改应用程序启动器代码。
不得将纯文本和 Inline
元素混合作为 TextBlock
的内容。
使用 Run
显示文本。然后将 Run.Foreground
属性 绑定到 Button
(或父 TextBlock
)。请参阅下面的示例。
你的按钮模板也是错误的。您不应将 ContentPresenter
包装到 TextBlock
中,尤其是当您添加另一个 TexBlock
作为 Button.Content
的值时。这会给你一个 TextBlock
嵌套到 TextBlock
:
<TextBlock> x:Name="TextBlockFromTemplate">
<TextBlock x:Name="TextBlockToReplaceContentPresenter" />
</TextBlock>
还将 ContentPresenter.HorizontalAlignment
绑定到模板化父项的 HorizontalContentAlignment
(ContentPresenter.VerticalAlignment
也是如此)。不要明确设置它,因为这会断开 Button.HorizontalContentAlignment
与模板的连接,使其无用。
您可以使用针对 Run
的 Style
,并将其添加到 ApplicationLauncherButton
的 Style
的 ResourceDictionary
中,以避免重复代码:
Generic.xaml
<Style TargetType="{x:Type local:ApplicationLauncherButton}">
<Style.Resources>
<Style TargetType="Run">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}" />
</Style>
</Style.Resources>
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="control"
TargetType="{x:Type local:ApplicationLauncherButton}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
TargetName="border"
Value="Orange" />
<Setter Property="BorderBrush"
TargetName="border"
Value="Red" />
<Setter Property="Foreground"
Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
例子
<local:ApplicationLauncherButton>
<TextBlock>
<Run>Designer</Run>
<LineBreak />
<Run>Application 4</Run>
</TextBlock>
</local:ApplicationLauncherButton>
有人要求我构建一个相对简单的应用程序启动器程序(以替换旧的基于 DOS 的菜单系统)。我在 WPF 中构建了应用程序,并创建了一个自定义的 class 派生自名为“ApplicationLauncherButton”的按钮。
我希望所有按钮都具有相同的“外观和感觉”,因此我决定它们的样式都相同。因此,我决定用我要创建的模板替换控件模板。为了让我的主要 window XAML 尽可能干净,我创建了一个单独的资源字典文件来保存模板并在 app.xaml.
中引用它这相当有效。但是,按钮上的某些文本很长,我想控制换行符出现的位置。通过将按钮文本包装在 TextBlock 中并在我需要的位置插入标签,可以相对轻松地完成此操作。不幸的是,这有一个副作用:不再应用我希望在鼠标悬停事件上发生的文本颜色更改。当按钮文本未包含在 TextBlock 中时,鼠标悬停格式会按预期工作,但我无法控制换行符出现的位置。
我花了几个小时试图弄清楚如何让它工作,但没有任何运气。我只使用 WPF 几个星期,所以可能有更简单的方法来完成我想做的事情。欢迎任何建议。
App.xaml
<Application x:Class="WPF1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Default\Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="WPF1.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:WPF1"
mc:Ignorable="d"
Title="Application Launcher" Height="787" Width="728"
Background="{StaticResource Default.DarkGreenBrush}" SizeChanged="Window_SizeChanged" WindowStartupLocation="CenterScreen">
<StackPanel Margin="5">
<GroupBox Header="Design Programs" Margin="5" Foreground="White" FontSize="11" FontWeight="Bold">
<WrapPanel>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp1.exe"
Click="ApplicationLauncherButton_Click">
Designer Application 1
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp2.exe"
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 2
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp3.exe"
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 3
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp4.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 4
</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\DesignerApp5.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Designer<LineBreak/>
Application 5
</TextBlock>
</local:ApplicationLauncherButton>
</WrapPanel>
</GroupBox>
<GroupBox Header="Utility Programs" Margin="5" Foreground="White" FontSize="11" FontWeight="Bold">
<WrapPanel>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp1.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 1</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp2.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 2</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp3.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 3</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp4.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 4</TextBlock>
</local:ApplicationLauncherButton>
<local:ApplicationLauncherButton
ApplicationUncPath="\server\applications\UtilityApp5.exe
Click="ApplicationLauncherButton_Click">
<TextBlock>
Utility<LineBreak/>
Application 5</TextBlock>
</local:ApplicationLauncherButton>
</WrapPanel>
</GroupBox>
</StackPanel>
</Window>
Button.xaml(在项目的\Themes\Default文件夹中)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF1">
<!-- Colors -->
<Color x:Key="Default.LightGreen">#509248</Color>
<Color x:Key="Default.DarkGreen">#014419</Color>
<Color x:Key="Button.Static.Background.Color">#FFDDDDDD</Color>
<Color x:Key="Button.Static.Border.Color">#FF707070</Color>
<Color x:Key="Button.Static.Foreground.Color">#FFFFFF</Color>
<Color x:Key="Button.MouseOver.Background.Color">#90D288</Color>
<Color x:Key="Button.MouseOver.Border.Color">#FF707070</Color>
<Color x:Key="Button.MouseOver.Foreground.Color">#EEEE00</Color>
<Color x:Key="Button.Pressed.Background.Color">#307228</Color>
<Color x:Key="Button.Pressed.Border.Color">#FF505050</Color>
<Color x:Key="Button.Disabled.Background.Color">#FFF4F4F4</Color>
<Color x:Key="Button.Disabled.Border.Color">#FFADB2B5</Color>
<Color x:Key="Button.Disabled.Foreground.Color">#FF838383</Color>
<!-- Brushes -->
<SolidColorBrush x:Key="Default.LightGreenBrush" Color="{StaticResource Default.LightGreen}"/>
<SolidColorBrush x:Key="Default.DarkGreenBrush" Color="{StaticResource Default.DarkGreen}"/>
<SolidColorBrush x:Key="Button.Static.Background.Brush" Color="{StaticResource Default.LightGreen}" />
<SolidColorBrush x:Key="Button.Static.Border.Brush" Color="{StaticResource Button.Static.Border.Color}"/>
<SolidColorBrush x:Key="Button.Static.Foreground.Brush" Color="{StaticResource Button.Static.Foreground.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Background.Brush" Color="{StaticResource Button.MouseOver.Background.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Border.Brush" Color="{StaticResource Button.MouseOver.Border.Color}"/>
<SolidColorBrush x:Key="Button.MouseOver.Foreground.Brush" Color="{StaticResource Button.MouseOver.Foreground.Color}"/>
<SolidColorBrush x:Key="Button.Pressed.Background.Brush" Color="{StaticResource Button.Pressed.Background.Color}"/>
<SolidColorBrush x:Key="Button.Pressed.Border.Brush" Color="{StaticResource Button.Pressed.Border.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Background.Brush" Color="{StaticResource Button.Disabled.Background.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Border.Brush" Color="{StaticResource Button.Disabled.Border.Color}"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground.Brush" Color="{StaticResource Button.Disabled.Foreground.Color}"/>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ApplicationLauncherButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background.Brush}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border.Brush}"/>
<Setter Property="Foreground" Value="{StaticResource Button.Static.Foreground.Brush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Width" Value="125"/>
<Setter Property="Height" Value="125"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="control" TargetType="{x:Type local:ApplicationLauncherButton}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<TextBlock x:Name="textBlock" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter x:Name="contentPresenter" Focusable="False" RecognizesAccessKey="True" Visibility="Visible"/>
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.MouseOver.Foreground.Brush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.MouseOver.Foreground.Brush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background.Brush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border.Brush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground.Brush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
附带说明一下,我按原样构建 window 的部分原因是我打算将应用程序信息移动到数据源,根据数据动态创建按钮和组.这将允许我添加/删除应用程序而无需修改应用程序启动器代码。
不得将纯文本和 Inline
元素混合作为 TextBlock
的内容。
使用 Run
显示文本。然后将 Run.Foreground
属性 绑定到 Button
(或父 TextBlock
)。请参阅下面的示例。
你的按钮模板也是错误的。您不应将 ContentPresenter
包装到 TextBlock
中,尤其是当您添加另一个 TexBlock
作为 Button.Content
的值时。这会给你一个 TextBlock
嵌套到 TextBlock
:
<TextBlock> x:Name="TextBlockFromTemplate">
<TextBlock x:Name="TextBlockToReplaceContentPresenter" />
</TextBlock>
还将 ContentPresenter.HorizontalAlignment
绑定到模板化父项的 HorizontalContentAlignment
(ContentPresenter.VerticalAlignment
也是如此)。不要明确设置它,因为这会断开 Button.HorizontalContentAlignment
与模板的连接,使其无用。
您可以使用针对 Run
的 Style
,并将其添加到 ApplicationLauncherButton
的 Style
的 ResourceDictionary
中,以避免重复代码:
Generic.xaml
<Style TargetType="{x:Type local:ApplicationLauncherButton}">
<Style.Resources>
<Style TargetType="Run">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}" />
</Style>
</Style.Resources>
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="control"
TargetType="{x:Type local:ApplicationLauncherButton}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
TargetName="border"
Value="Orange" />
<Setter Property="BorderBrush"
TargetName="border"
Value="Red" />
<Setter Property="Foreground"
Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
例子
<local:ApplicationLauncherButton>
<TextBlock>
<Run>Designer</Run>
<LineBreak />
<Run>Application 4</Run>
</TextBlock>
</local:ApplicationLauncherButton>