英文:
WPF Custom controls don't have rendering styles
问题
I create a custom control library like this:
enter image description here
KiwiButton.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KiwiWPFControl.Controls">
<Style x:Key="KiwiButtonStyle" TargetType="local:KiwiButton">
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
<GradientStop Color="#FF00AA11" Offset="0"/>
<GradientStop Color="#FF00AA88" Offset="0.5"/>
<GradientStop Color="#FF00AAA6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KiwiButton">
<Border BorderThickness="1" CornerRadius="15" Background="Transparent">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Background" Value="#AA00AAA6"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style BasedOn="{StaticResource KiwiButtonStyle}" TargetType="local:KiwiButton"/>
</ResourceDictionary>
Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/KiwiWPFControl;component/Themes/KiwiButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
KiwiButton.cs:
namespace KiwiWPFControl.Controls
{
public class KiwiButton : Button
{
static KiwiButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(KiwiButton), new FrameworkPropertyMetadata(typeof(KiwiButton)));
}
}
}
And I use this button like this
App.xaml:
<Application x:Class="KiwiWPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KiwiWPFDemo"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/KiwiWPFControl;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml:
<Window x:Class="KiwiWPFDemo.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:KiwiWPFDemo"
mc:Ignorable="d"
xmlns:kiwi="clr-namespace:KiwiWPFControl.Controls;assembly=KiwiWPFControl"
Height="450" Width="800">
<Grid>
<kiwi:KiwiButton Width="200" Height="100" Content="12"/>
</Grid>
</Window>
It compiles and runs successfully
But it shows this:enter image description here
How to make the style of the control take effect??
英文:
I create a custom control library like this:
enter image description here
KiwiButton.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KiwiWPFControl.Controls">
<Style x:Key="KiwiButtonStyle" TargetType="local:KiwiButton" >
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
<GradientStop Color="#FF00AA11" Offset="0"/>
<GradientStop Color="#FF00AA88" Offset="0.5"/>
<GradientStop Color="#FF00AAA6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KiwiButton" >
<Border BorderThickness="1" CornerRadius="15" Background="Transparent">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers >
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Background" Value="#AA00AAA6"/>
</Trigger >
</ControlTemplate.Triggers >
</ControlTemplate >
</Setter.Value>
</Setter>
</Style >
<Style BasedOn="{StaticResource KiwiButtonStyle}" TargetType="local:KiwiButton"/>
</ResourceDictionary>
Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/KiwiWPFControl;component/Themes/KiwiButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
KiwiButton.cs:
namespace KiwiWPFControl.Controls{
public class KiwiButton : Button
{
static KiwiButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(KiwiButton), new FrameworkPropertyMetadata(typeof(KiwiButton)));
}
}
}
And I use this button like this
App.xaml:
<Application x:Class="KiwiWPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KiwiWPFDemo"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/KiwiWPFControl;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml:
<Window x:Class="KiwiWPFDemo.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:KiwiWPFDemo"
mc:Ignorable="d"
xmlns:kiwi="clr-namespace:KiwiWPFControl.Controls;assembly=KiwiWPFControl"
Height="450" Width="800">
<Grid>
<kiwi:KiwiButton Width="200" Height="100" Content="12"/>
</Grid>
</Window>
It compiles and runs successfully
But it shows this:enter image description here
How to make the style of the control take effect??
答案1
得分: 0
在你的控件模板中,你应该使用TemplateBinding
来绑定背景属性。在你的标记中,你设置了该属性,但没有在任何地方使用它。
这强调了你在模板化中需要记住的一点。
一旦你替换了控件的模板,除了你设置的内容之外,视觉上不会有其他内容。
然后,你可以潜在地删除设置DefaultStyleKeyProperty
的代码行。
<Style TargetType="local:KiwiButton">
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
<GradientStop Color="#FF00AA11" Offset="0"/>
<GradientStop Color="#FF00AA88" Offset="0.5"/>
<GradientStop Color="#FF00AAA6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KiwiButton">
<Border BorderThickness="1" CornerRadius="15" Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Background" Value="#AA00AAA6"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此外,在kiwibutton.xaml
中,你删除了以下行:
<Style BasedOn="{StaticResource KiwiButtonStyle}" TargetType="local:KiwiButton"/>
正如Clemens在评论中指出的那样。
当你设置TargetType
时,自动获取该类型作为x:Key
。有些人喜欢明确设置它:
x:Key="{x:Type local:KiwiButton}"
这是我为几个客户工作时的标准做法,我也习惯这样做。
英文:
In your controltemplate, you should use templatebinding with the background. In your markup, you set the property but it is not used anywhere.
This highlights one of the things you need to bear in mind with templating.
Once you've replaced the template of a control then there is nothing there visually other than whatever you set.
You can then potentially remove the line of code sets defaultstylekeyproperty
<Style TargetType="local:KiwiButton" >
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
<GradientStop Color="#FF00AA11" Offset="0"/>
<GradientStop Color="#FF00AA88" Offset="0.5"/>
<GradientStop Color="#FF00AAA6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KiwiButton" >
<Border BorderThickness="1" CornerRadius="15"
Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers >
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Background" Value="#AA00AAA6"/>
</Trigger >
</ControlTemplate.Triggers >
</ControlTemplate >
</Setter.Value>
</Setter>
</Style >
BTW the above style is all that's in my kiwibutton.xaml, I removed the line:
<Style BasedOn="{StaticResource KiwiButtonStyle}" TargetType="local:KiwiButton"/>
As Clemens pointed out in comments.
When you set targettype you automatically get the type as an x:Key.
Some people prefer to also set that explicitly.
x:Key="{x:Type local:KiwiButton}"
This a standard at several clients I have worked for and I am in the habit of doing this myself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论