将ControlTemplate与用户控件混合使用是个好主意吗?

时间:2009-02-08 05:25:44

标签: wpf user-controls controltemplate

是否有可能和良好的想法让用户控制(public MyControl: UserControl)支持ControlTemplate和现有内容?我已经了解ControlTemplate只应在从Control(public MyControl: Control)继承时使用,但我发现如果UserControl.xaml为空,也可以将它们与UserControl一起使用

想象一下,我有一个控件,它有两个并排的矩形,如下所示:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid ShowGridLines="true" Height="100" Width="100"> 
        <Grid.ColumnDefinitions> 
            <ColumnDefinition/> 
            <ColumnDefinition/> 
        </Grid.ColumnDefinitions> 
        <Rectangle Name="left" Grid.Column="0" Height="90" Fill="LightBlue"/> 
        <Rectangle Name="right" Grid.Column="1" Height="100" Fill="LightGreen"/> 
    </Grid> 
</Page> 

我希望控件的用户能够用他想要使用的FrameworkElement替换那些矩形。所以我需要一个ControlTemplate

但是在99%的情况下,控件的用户对现有功能感到满意,所以我希望他能够说:

代码背后:

mycontrol.Left.Fill = ....

XAML:

<mycontrol>
<mycontrol.Left.Fill = "Red"/>
</mycontrol>

这似乎不可能,因为如果我支持控件模板,我真的没有任何UI元素或xaml。我只有文件背后的代码。我想我可以有一个DependencyProperty Left,但只要我没有某种容器就可以容纳那些效果不佳的内容。我必须在代码隐藏文件后创建网格。看起来不是一个好主意。

最后我希望能够使用泛型,以便用户可以指定部件的类型:

MyControl mycontrol<TLeft, TRight> = new MyControl<Rectangle, Button>();

由于类型安全性(无需将FrameworkElement转换为正确的类型),这将有助于代码隐藏。不幸的是,我不认为XAML方面真的支持泛型。

是否有任何解决此问题的方法,或者它是否真的“继承自控制以支持ControlTemplate但失去控件的易用性。继承UserControl以便支持易用性但丢失{ {1}}支持“?

1 个答案:

答案 0 :(得分:2)

向控件添加依赖项属性:

public static DependencyProperty LeftFillProperty = DependencyProperty.
   Register("LeftFill", typeof(Brush), typeof(MyControl));

public Brush LeftFill
{
   get { return (Brush)GetValue(LeftFillProperty); }
   set { SetValue(LeftFillProperty,value); }
}

然后在默认控件模板中使用:

<Rectangle Name="left" Grid.Column="0" Height="90" Fill="{TemplateBinding LeftFill}"/>

这将让你使用(C#)

ctrl.LeftFill = Brushes.Red;

或(XAML)

<c:MyControl LeftFill="Red"/>

当您使用默认模板时,当有人编写新的控件模板时,他们有责任决定如何处理LeftFill属性(或完全忽略它)。

顺便说一下,您应该考虑将名称从“左”和“右”更改为其他名称(“MasterPanel”和“DetailPanel”,“FoldersArea”和“FilesArea”,无论您的控件中的逻辑用法是什么),将解决使用模板替换默认模板的问题,该模板以不同的布局显示相同的数据(例如,顶部和底部而不是左侧和右侧)。