如何将多边形填充 属性 绑定到按钮的背景 属性?
How can I bind a Polygon Fill property to the Background property of the button?
我使用 Styles 和 ControlTemplates 创建了一个 HexagonButton。此时 HexagonButton 背景为蓝色。
我希望能够在加载按钮时或至少在将其放入 canvas 时设置其背景颜色。不幸的是,当我将按钮置于 canvas 并尝试将背景更改为其他颜色(例如红色)时,所有连接到 IsMouseOver、IsPressed 的效果都不起作用。
是否可以连接这个
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
有了这个
<Button Name ="OO" Width="100" Height="100" Background ="Red" Canvas.Left="176" Canvas.Top="120" Click="Button_Click"/>
我不太明白如何解决我的问题,需要一些建议才能继续朝着正确的方向尝试。我应该创建一个用户控件或类似的东西吗?
或者也许可以使用 DynamicResources 解决这个问题,但是如何解决。
这是完整的代码。
<Window x:Class="ForthHexagonButtonWR.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:ForthHexagonButtonWR"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="HighlightBackground" >
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset=".6" />
</RadialGradientBrush>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="PressedBackground">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset="1" />
</RadialGradientBrush>
<SolidColorBrush x:Key="DefaultBackground" Color="Blue" ></SolidColorBrush>
<SolidColorBrush Color="Gray" x:Key="DisabledBackground"></SolidColorBrush>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="Border">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset="1" />
</RadialGradientBrush>
<!-- The style that applies the button control template. -->
<Style TargetType="{x:Type Button}" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="{StaticResource Border}"></Setter>
<Setter Property="Background" Value="{StaticResource DefaultBackground}"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HighlightBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource PressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{StaticResource DisabledBackground}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Window.Resources>
<Canvas>
<Button Name ="OO" Width="100" Height="100" Canvas.Left="176" Canvas.Top="120" Click="Button_Click"/>
<Button Name ="O1" Width="100" Height="100" Canvas.Left="176" Canvas.Top="34" Click="Button_Click"/>
<Button Name ="O2" Width="100" Height="100" Canvas.Left="250" Canvas.Top="76" Click="Button_Click"/>
<Button Name ="O3" Width="100" Height="100" Canvas.Left="251" Canvas.Top="162" Click="Button_Click"/>
<Button Name ="O4" Width="100" Height="100" Canvas.Left="177" Canvas.Top="206" Click="Button_Click"/>
<Button Name ="O5" Width="100" Height="100" Canvas.Left="103" Canvas.Top="162" Click="Button_Click"/>
<Button Name ="O6" Width="100" Height="100" Canvas.Left="101" Canvas.Top="76" Click="Button_Click"/>
</Canvas>
当您从外部为按钮设置 Background
时,内部的样式触发器 setter 将无法更改 Background
,因为 DependencyProperty value precedence(在这种情况下,本地设置将通过样式覆盖设置。
因此您应该直接更改内部多边形的 Fill
,而不是模板化父项(按钮)的 Background
。但是,您需要将所有触发器移动到 ControlTemplate
(使用 ControlTemplate 的触发器而不是样式的触发器):
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource HighlightBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource PressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource DisabledBackground}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="{StaticResource Border}"></Setter>
<Setter Property="Background" Value="{StaticResource DefaultBackground}"></Setter>
</Style>
我们使用 Setter
的 TargetName
来指示哪个元素(在 ControlTemplate 的范围内)具有要设置的 属性。
这是因为您可能会在加载控件时用您定义的背景覆盖背景。请参阅已发布 answer.
您可能需要使用 DynamicResource
来解决问题。
我使用 Styles 和 ControlTemplates 创建了一个 HexagonButton。此时 HexagonButton 背景为蓝色。
我希望能够在加载按钮时或至少在将其放入 canvas 时设置其背景颜色。不幸的是,当我将按钮置于 canvas 并尝试将背景更改为其他颜色(例如红色)时,所有连接到 IsMouseOver、IsPressed 的效果都不起作用。
是否可以连接这个
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
有了这个
<Button Name ="OO" Width="100" Height="100" Background ="Red" Canvas.Left="176" Canvas.Top="120" Click="Button_Click"/>
我不太明白如何解决我的问题,需要一些建议才能继续朝着正确的方向尝试。我应该创建一个用户控件或类似的东西吗?
或者也许可以使用 DynamicResources 解决这个问题,但是如何解决。
这是完整的代码。
<Window x:Class="ForthHexagonButtonWR.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:ForthHexagonButtonWR"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="HighlightBackground" >
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset=".6" />
</RadialGradientBrush>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="PressedBackground">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset="1" />
</RadialGradientBrush>
<SolidColorBrush x:Key="DefaultBackground" Color="Blue" ></SolidColorBrush>
<SolidColorBrush Color="Gray" x:Key="DisabledBackground"></SolidColorBrush>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.5,0.5" x:Key="Border">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Blue" Offset="1" />
</RadialGradientBrush>
<!-- The style that applies the button control template. -->
<Style TargetType="{x:Type Button}" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="{StaticResource Border}"></Setter>
<Setter Property="Background" Value="{StaticResource DefaultBackground}"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HighlightBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource PressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{StaticResource DisabledBackground}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Window.Resources>
<Canvas>
<Button Name ="OO" Width="100" Height="100" Canvas.Left="176" Canvas.Top="120" Click="Button_Click"/>
<Button Name ="O1" Width="100" Height="100" Canvas.Left="176" Canvas.Top="34" Click="Button_Click"/>
<Button Name ="O2" Width="100" Height="100" Canvas.Left="250" Canvas.Top="76" Click="Button_Click"/>
<Button Name ="O3" Width="100" Height="100" Canvas.Left="251" Canvas.Top="162" Click="Button_Click"/>
<Button Name ="O4" Width="100" Height="100" Canvas.Left="177" Canvas.Top="206" Click="Button_Click"/>
<Button Name ="O5" Width="100" Height="100" Canvas.Left="103" Canvas.Top="162" Click="Button_Click"/>
<Button Name ="O6" Width="100" Height="100" Canvas.Left="101" Canvas.Top="76" Click="Button_Click"/>
</Canvas>
当您从外部为按钮设置 Background
时,内部的样式触发器 setter 将无法更改 Background
,因为 DependencyProperty value precedence(在这种情况下,本地设置将通过样式覆盖设置。
因此您应该直接更改内部多边形的 Fill
,而不是模板化父项(按钮)的 Background
。但是,您需要将所有触发器移动到 ControlTemplate
(使用 ControlTemplate 的触发器而不是样式的触发器):
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Polygon x:Name="HexagonPolygon" Points="1,0 0.50046, 0.86576 -0.50046, 0.86576 -1,0 -0.50046,-0.86576 0.50046,-0.86576" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Background}" StrokeThickness="2" Stretch="Uniform"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource HighlightBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource PressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="HexagonPolygon" Property="Fill" Value="{StaticResource DisabledBackground}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="{StaticResource Border}"></Setter>
<Setter Property="Background" Value="{StaticResource DefaultBackground}"></Setter>
</Style>
我们使用 Setter
的 TargetName
来指示哪个元素(在 ControlTemplate 的范围内)具有要设置的 属性。
这是因为您可能会在加载控件时用您定义的背景覆盖背景。请参阅已发布 answer.
您可能需要使用 DynamicResource
来解决问题。