问题
I've created a custom control similar to a button. I want to override his default properties, but it works strangely.
UserControl 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 Code Behind (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();
}
}
Result
But, when I try to set the Background property it colors the background of the control, and not the ellipse, when I try to set the Content, it overrides the button, etc...
Example: Background="Red"
回答1:
You could define a ControlTemplate
for the UserControl
:
<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>
Using a TemplateBinding
for a property of en element in the template, you can set this property of the UserControl
to change the property of the element in the template:
<local:Button Background="Red" Content="" />
回答2:
UserControl has its Backround
and Content
properties, which are wrappers for DependencyProperties.
You are trying to shadow them using new
keyword before property, but it fails. (set a breakpoint in setter: breakpoint is never hit)
When setting Background="smth"
or Content="smth"
from xaml, base properties are detected, and additionally WPF doesn't use wrapper properties, it uses DependencyObject.SetValue()
directly. And setting base Content simply removes existing Grid with Ellipse.
Rename Background -> CustomBackground, Content -> CustomContent and set them. Then MyButton will work.
Much better is to reuse base Content and Background though (bind them to Ellipse and Lable in MyButton xaml).
来源:https://stackoverflow.com/questions/51836773/custom-control-how-to-override-default-properties