【问题标题】:Is it good idea to mix ControlTemplate with user control?将 ControlTemplate 与用户控件混合使用是个好主意吗?
【发布时间】:2009-02-08 05:25:44
【问题描述】:

让用户控制 (public MyControl: UserControl) 同时支持 ControlTemplates 和现有内容是否可能并且是一个的想法?我知道 ControlTemplates 只能在您从 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> 

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

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

后面的代码:

mycontrol.Left.Fill = ....

XAML:

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

这似乎是不可能的,因为如果我支持控件模板,我真的没有任何 UI 元素或 xaml。我只有文件后面的代码。我想我可以有一个DependencyPropertyLeft,但只要我没有某种容器来保存不会有多大好处的内容。我必须在文件后面的代码中创建网格。似乎不是一个好主意。

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

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

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

这个问题有什么解决办法还是真的“从Control继承以支持ControlTemplates但失去控件的易用性。从UserControl继承以支持简单易用但失去ControlTemplate支持”?

【问题讨论】:

    标签: wpf user-controls controltemplate


    【解决方案1】:

    给控件添加依赖属性:

    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 属性(或完全忽略它)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 1970-01-01
      • 2020-11-08
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      相关资源
      最近更新 更多