特别感谢@BionicCode 帮助我入门。
所以我试图更好地理解 CustomControl 样式。因此,我创建了一个名为 MyToggleButton 的自定义切换按钮,并且我想在另一个名为 MyCustomControl 的自定义控件中使用它。
这是我的切换代码:
public class MyToggleButton : ToggleButton
{
public static ComponentResourceKey ButtonBrushKey =
new ComponentResourceKey(typeof(MyToggleButton), "ButtonBrush");
static MyToggleButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyToggleButton),
new FrameworkPropertyMetadata(typeof(MyToggleButton)));
}
}
在 Generic.xaml 中:
<SolidColorBrush x:Key="{x:Static ctrl:MyToggleButton.ButtonBrushKey}" Color="Red" />
<Style TargetType="{x:Type ctrl:MyToggleButton}">
<Setter Property="Background" Value="SteelBlue"/>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Height" Value="28"/>
<Setter Property="Width" Value="65"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:MyToggleButton}">
<Border x:Name="back"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!--BUTTON-->
<Border x:Name="button"
Grid.Column="0"
Grid.ColumnSpan="2"
Background="{DynamicResource {x:Static ctrl:MyToggleButton.ButtonBrushKey}}"
Width="16"
Height="16"
Margin="2"
CornerRadius="3"
HorizontalAlignment="Left">
<Path x:Name="icon"
Fill="{DynamicResource {x:Static ctrl:MyToggleButton.ButtonBrushKey}}"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="2"
Data="{Binding OnPathData, RelativeSource={RelativeSource TemplatedParent}}"/>
</Border>
<!--TEXT-->
<TextBlock x:Name="text"
Grid.Column="1"
Text="On"
FontSize="12"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后,我想在MyCustomControl中使用它。
我正在尝试从 MyCustomControl 中设置 Toggle 上的 ButtonBrush 资源。它没有任何作用。请参阅此处的第一行:
<SolidColorBrush x:Key="{x:Static toggle:MyToggleButton.ButtonBrushKey}" Color="Green" />
<Style TargetType="{x:Type ctrl:MyCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:MyCustomControl}">
<Border BorderBrush="SteelBlue"
BorderThickness="2"
Background="LightGray">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<toggle:MyToggleButton Grid.Column="0"
VerticalAlignment="Center"
Height="45"
Width="100"
Margin="5,0,0,0"/>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Text="Some Text"
FontWeight="Bold"
Margin="5,0,0,0"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但是,如果我将两个控件都放在一个窗口上,我可以在那里更改切换按钮的 ButtonBrush。
<Window.Resources>
<!--This makes ALL toggle buttons have a yellow inner button-->
<SolidColorBrush x:Key="{x:Static toggle:MyToggleButton.ButtonBrushKey}" Color="Yellow" />
</Window.Resources>
如何从 MyCustomControl 内部设置 ButtonBrush?
我将向您展示一个包含一个元素的简单示例。 我认为从中您将了解如何需要重新配置您的解决方案。
using System.Windows;
using System.Windows.Controls;
namespace MyCustomControl.Widget
{
// The key is declared in a separate class.
// This solution is not mandatory.
// I did it this way to demonstrate the independence of the key from the element.
// If it is more convenient for you, you can declare them in one class.
public static class ExampleComponentResourceKey
{
public static ComponentResourceKey SomeBrushKey =
new ComponentResourceKey(typeof(ExampleComponentResourceKey), nameof(SomeBrushKey)[0..^3]);
}
public class SomeControl : Control
{
static SomeControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SomeControl),
new FrameworkPropertyMetadata(typeof(SomeControl)));
}
}
}
Generic.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyCustomControl.Widget">
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:ExampleComponentResourceKey}, ResourceId=SomeBrush}"
Color="Red"/>
<Style TargetType="{x:Type local:SomeControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SomeControl">
<Label Margin="20" Background="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type local:ExampleComponentResourceKey}, ResourceId=SomeBrush}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
示例#1:
<Window x:Class="MyCustomControl.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wacky="clr-namespace:MyCustomControl.Widget;assembly=MyCustomControl.Widget"
mc:Ignorable="d"
Title="Wacky Widget Control Demo"
WindowStartupLocation="CenterScreen"
Height="450"
Width="800">
<Window.Resources>
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type wacky:ExampleComponentResourceKey}, ResourceId=SomeBrush}"
Color="Green"/>
</Window.Resources>
<Grid>
<wacky:SomeControl/>
</Grid>
</Window>
示例#2:
<Window x:Class="MyCustomControl.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wacky="clr-namespace:MyCustomControl.Widget;assembly=MyCustomControl.Widget"
mc:Ignorable="d"
Title="Wacky Widget Control Demo"
WindowStartupLocation="CenterScreen"
Height="450"
Width="800">
<UniformGrid Rows="1">
<wacky:SomeControl>
<FrameworkElement.Resources>
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type wacky:ExampleComponentResourceKey}, ResourceId=SomeBrush}"
Color="Green"/>
</FrameworkElement.Resources>
</wacky:SomeControl>
<wacky:SomeControl/>
</UniformGrid>
</Window>