自定义控件:如何覆盖默认属性?
Custom control: How to override default properties?
我创建了一个类似于按钮的自定义控件。
我想覆盖他的默认属性,但效果很奇怪。
用户控件Xaml
<UserControl x:Class="project.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Grid>
<Ellipse x:Name="structure" Fill="Black" Stroke="White" StrokeThickness="2"/>
<Label x:Name="content" Content="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontFamily="Segoe MDL2 Assets" FontWeight="Bold" FontSize="16"/>
</Grid>
</UserControl>
UserControl 代码隐藏 (C#)
/// <summary>A simple custom button.</summary>
public partial class MyButton : UserControl
{
/// <summary>Background color.</summary>
public new Brush Background { get => structure.Fill; set => structure.Fill = value; }
/// <summary>Foreground color.</summary>
public new Brush Foreground { get => content.Foreground; set => content.Foreground = value; }
/// <summary>Stroke color.</summary>
public Brush Stroke { get => structure.Stroke; set => structure.Stroke = value; }
/// <summary>Stroke thickness.</summary>
public double StrokeThickness { get => structure.StrokeThickness; set => structure.StrokeThickness = value; }
/// <summary>Font family.</summary>
public new FontFamily FontFamily { get => content.FontFamily; set => content.FontFamily = value; }
/// <summary>Font weight.</summary>
public new FontWeight FontWeight { get => content.FontWeight; set => content.FontWeight = value; }
/// <summary>Font size.</summary>
public new double FontSize { get => content.FontSize; set => content.FontSize = value; }
/// <summary>Content.</summary>
public new object Content { get => content.Content; set => content.Content = value; }
/// <summary>Inizialize new <see cref="MyButton"/>.</summary>
public MyButton()
{
InitializeComponent();
}
}
结果
但是,当我尝试设置背景时 属性 它会为控件的背景着色,而不是椭圆,当我尝试设置内容时,它会覆盖按钮等...
示例:Background="Red"
UserControl 有其 Backround
和 Content
属性,它们是 DependencyProperties 的包装器。
您试图在 属性 之前使用 new
关键字隐藏它们,但失败了。 (在setter中设置断点:永远不会命中断点)
当从 xaml 设置 Background="smth"
或 Content="smth"
时,检测基本属性,此外 WPF 不使用包装器属性,它直接使用 DependencyObject.SetValue()
。设置基本内容只是简单地删除现有的带椭圆的网格。
重命名背景 -> CustomBackground、内容 -> CustomContent 并设置它们。然后 MyButton 将起作用。
更好的方法是重用基础内容和背景(将它们绑定到 MyButton xaml 中的 Ellipse 和 Lable)。
您可以为 UserControl
定义一个 ControlTemplate
:
<UserControl x:Class="project.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<Ellipse x:Name="structure" Fill="{TemplateBinding Background}" Stroke="White" StrokeThickness="2"/>
<Label x:Name="content" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontFamily="Segoe MDL2 Assets" FontWeight="Bold" FontSize="16"/>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
在模板中使用 TemplateBinding
作为 en 元素的 属性,您可以设置 UserControl
的 属性 来更改 属性模板中元素的数量:
<local:Button Background="Red" Content="" />
我创建了一个类似于按钮的自定义控件。 我想覆盖他的默认属性,但效果很奇怪。
用户控件Xaml
<UserControl x:Class="project.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Grid>
<Ellipse x:Name="structure" Fill="Black" Stroke="White" StrokeThickness="2"/>
<Label x:Name="content" Content="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontFamily="Segoe MDL2 Assets" FontWeight="Bold" FontSize="16"/>
</Grid>
</UserControl>
UserControl 代码隐藏 (C#)
/// <summary>A simple custom button.</summary>
public partial class MyButton : UserControl
{
/// <summary>Background color.</summary>
public new Brush Background { get => structure.Fill; set => structure.Fill = value; }
/// <summary>Foreground color.</summary>
public new Brush Foreground { get => content.Foreground; set => content.Foreground = value; }
/// <summary>Stroke color.</summary>
public Brush Stroke { get => structure.Stroke; set => structure.Stroke = value; }
/// <summary>Stroke thickness.</summary>
public double StrokeThickness { get => structure.StrokeThickness; set => structure.StrokeThickness = value; }
/// <summary>Font family.</summary>
public new FontFamily FontFamily { get => content.FontFamily; set => content.FontFamily = value; }
/// <summary>Font weight.</summary>
public new FontWeight FontWeight { get => content.FontWeight; set => content.FontWeight = value; }
/// <summary>Font size.</summary>
public new double FontSize { get => content.FontSize; set => content.FontSize = value; }
/// <summary>Content.</summary>
public new object Content { get => content.Content; set => content.Content = value; }
/// <summary>Inizialize new <see cref="MyButton"/>.</summary>
public MyButton()
{
InitializeComponent();
}
}
结果
但是,当我尝试设置背景时 属性 它会为控件的背景着色,而不是椭圆,当我尝试设置内容时,它会覆盖按钮等...
示例:Background="Red"
UserControl 有其 Backround
和 Content
属性,它们是 DependencyProperties 的包装器。
您试图在 属性 之前使用 new
关键字隐藏它们,但失败了。 (在setter中设置断点:永远不会命中断点)
当从 xaml 设置 Background="smth"
或 Content="smth"
时,检测基本属性,此外 WPF 不使用包装器属性,它直接使用 DependencyObject.SetValue()
。设置基本内容只是简单地删除现有的带椭圆的网格。
重命名背景 -> CustomBackground、内容 -> CustomContent 并设置它们。然后 MyButton 将起作用。
更好的方法是重用基础内容和背景(将它们绑定到 MyButton xaml 中的 Ellipse 和 Lable)。
您可以为 UserControl
定义一个 ControlTemplate
:
<UserControl x:Class="project.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<Ellipse x:Name="structure" Fill="{TemplateBinding Background}" Stroke="White" StrokeThickness="2"/>
<Label x:Name="content" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontFamily="Segoe MDL2 Assets" FontWeight="Bold" FontSize="16"/>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
在模板中使用 TemplateBinding
作为 en 元素的 属性,您可以设置 UserControl
的 属性 来更改 属性模板中元素的数量:
<local:Button Background="Red" Content="" />