C# 自定义控件库中依赖项属性的WPF组合优于继承
简而言之:我不想在每次编写自定义控件时都实现依赖属性C# 自定义控件库中依赖项属性的WPF组合优于继承,c#,wpf,C#,Wpf,简而言之:我不想在每次编写自定义控件时都实现依赖属性HighlightBrush,从而重复我自己 下面是两个令人讨厌的代码重复示例: public class MyButton : Button { public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(MyButton),
HighlightBrush
,从而重复我自己
下面是两个令人讨厌的代码重复示例:
public class MyButton : Button
{
public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(MyButton), new PropertyMetadata(default(Brush)));
public Brush HighlightBrush
{
get { return (Brush) GetValue(HighlightBrushProperty); }
set { SetValue(HighlightBrushProperty, value); }
}
}
public class MyTextBox : TextBox
{
public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(MyTextBox), new PropertyMetadata(default(Brush)));
public Brush HighlightBrush
{
get { return (Brush)GetValue(HighlightBrushProperty); }
set { SetValue(HighlightBrushProperty, value); }
}
}
为完整起见,请在Generic.xaml
中使用HighlightBrush
:
<Style TargetType="{x:Type custom:MyButton}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom:MyButton}">
<Border x:Name="Border" Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{Binding HighlightBrush, RelativeSource={RelativeSource TemplatedParent}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type custom:MyTextBox}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom:MyTextBox}">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="PART_ContentHost" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{Binding HighlightBrush, RelativeSource={RelativeSource TemplatedParent}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
问题:如何避免依赖属性上的代码重复?我不能引入另一个基类,因为没有多重继承。我不能使用composition,因为依赖项属性需要使用具体类型创建。可能附加的依赖属性有帮助,但如何在控制类和XAML中与它们交互
(我想
TextBlock.Text
和TextBox.Text
与我的问题非常相似。)您可以使用AttachedProperties并在XAML中与它们进行交互,这只需要做更多的工作,您就可以习惯语法
例如,我希望任意控件类型具有Geometria
(Geometry)属性,因此我创建了一个AttachedProperty类来包含它(葡萄牙语名称):
然后,在XAML中,我将此属性设置为:
<Button
controls:PropriedadeAnexada.Geometria="{StaticResource ÍconeNovoExame}"
Style="{StaticResource BotãoGeometria}"
/>
<ControlTemplate
x:Key="ControleGeometriaTemplate"
TargetType="{x:Type Control}"
>
<Grid x:Name="root">
<Path
x:Name="ícone"
Data="{Binding Path=(local:PropriedadeAnexada.Geometria), RelativeSource={RelativeSource TemplatedParent}}"
/>
</Grid>
</ControlTemplate>
为了满足我的需要:我仍然必须添加
公共几何HighlightBrush{get{return PropriedadeAnexada.GetGeometria(this);}set{PropriedadeAnexada.SetGeometria(this,value);}
!而是不需要使用local:PropriedadeAnexada.
前缀绑定。这是一个可以接受的解决方案!好吧,我想如果你想在多个类上重用同一个实现,而不是通过继承,你仍然需要把这个功能(在这种情况下是dependencProperty)放在某个类中,这就是为什么需要静态类作为占位符的原因。此外,由于该属性不在目标类定义中,因此必须使用额外的语法在XAML中引用它。我不知道还有其他方法。不幸的是,这种模式给我带来了很多麻烦:。就我个人而言,我不这样做。但那不是你的错!即使是我也相信解决方案应该有效。。。这是解决方案标记。最后;-)谢谢你的反馈!好的编码!
<ControlTemplate
x:Key="ControleGeometriaTemplate"
TargetType="{x:Type Control}"
>
<Grid x:Name="root">
<Path
x:Name="ícone"
Data="{Binding Path=(local:PropriedadeAnexada.Geometria), RelativeSource={RelativeSource TemplatedParent}}"
/>
</Grid>
</ControlTemplate>