• WPF学习笔记:Templates for uncommon controls


    Templates for uncommon controls

    http://msdn.microsoft.com/en-us/magazine/cc135986.aspx

    是该文章的读书摘记

    以前的控件其外观代码和逻辑代码是帮定在一起的,如果你想改变一个控件的外观,你需要从那个控件的类派生,重写显示外观部分的代码。甚至有的时候,这样做也达不到你的目标。而在WPF中,逻辑和外观代码可以分离。利用Template可以很方便的改变控件的外观而不改变其功能。所有的WPF控件都有默认的 Template,你可以方便的替换鲜有的template而改Control的外观和显示。

    Element Control的区别

    WPFControl类从FrameworkElement类派生 ,像TextBlock, Image, Panel, Decorator等都从FrameworkElement直接派生,所以他们不是Control.

    首先Control增加了很多属性,例如Foreground, Background 以及五个与Font有关的属性

    其次Control增加了IsTabStopTabIndex属性,这使得Control可以相应Tab键的焦点切换,而FrameworkElement 则没有这个功能,一句话,FrameworkElement仅仅是为了外观,而 Control还增加了交互。

    再者,Controltemplate, 可以被替换template而改变外观,template基本上就是代表控件外观的一颗视觉树,当然也包括响应属性变化和事件的一些triggers

    所以如果你要创建自己的Control那么很重要的一点就是你要提供可替换的默认的template,尽管这不是必须的,但是这样做无疑会极大地改善你的Control的易用性。

    要为你的Control DLL提供一个可被替换的默认的Template, 你必须遵守WPF的严格的规则:

    1. 你的源代码项目下必须有一个Theme目录,包含一个叫General.xaml的文件

    2. General.xaml是一个StyleResourceDictionary

    3. Style中必须包含设置Template属性的Section

    <RecourceDictonary>

                   <Style TargetType="cc:CaladendarDay">

                                  <Setter Property="Template">

                                                 <Setter.Value>

                                                                               <ControlTemplate TargetType="..." >

                                                                                                             .....

                                                                               </ControlTemplate>

                                                 </Setter.Value>

                                  </Setter>

                   </Style>

    </ResourceDictonary>

    4. 在你的控件类的静态构造函数中改变DefaultStyleKeyProperty属性的默认值:

    一般来说你设计一个控件,会从Control派生,并且增加一些属性。那么这里最好背后都是用DependencyProprty, 以使得这些属性可以Data Binding,并且利用Routed Event机制,在你的属性改变的时候,其他相关的对象得到通知。

    如果你需要属性已经在其他类里面定义过了,不要重新定义它,需要AddOwner

    使用DependencyProperty.OverrideMetaData可以用来改变从父类Control继承过来的Dependency属性的默认值,以及注册一个回调函数在属性改变的时候被0调用。

     覆盖OnApplyTemplate函数,以便检验Template的合法性以及建立与代码与template的连接,因为你或许需要Template中有指定的part, 例如ItemsControl都有一个叫PART_Panelpanal

    template中使用TemplateBinding绑定到那些新定义的DependencyProperty, 这样这些属性的改变就会反映到控件的外观上。对于那些可以通过视觉树从Control类继承的属性则不需要做任何处理,会自动应用到控件的外观上。例如 Foreground以及5个与Font相关的属性就会自动的应用于控件的外观,而不需要我们在Template中使用TemplateBinding来绑定。

    Template中应该尽量少的使用硬编码来设置一些属性的值,这样使用控件的人如果需要修改这些默认值就会很麻烦。一种可行的方法是,直接在Style中设置这些值,而不是在Template中设置这些值。这样控件的使用者就可以很方便的修改这些值。

    如果你的代码会假定Template 中必须有某些类型的部件,那么最好用TemplatePart性在你的Control的派生类上来标明。

    [TemplatePart(Name="PART_Panel", Type=TypeOf(Panel))]

    public class CalandarDay: Control

    { ....

    }

    你的Control派生类最好也可以暴露出一些RoutedCommand对象,使得 Template可以帮定以执行一些功能

    public static readonly RoutedCommand NextMonthCoommand = new RoutedCommand("NextMonth", typeof(CalendarMonth));

    其实只有少数WPF控件可以绑定到RoutedCommand, ButtonBase, MenuItem, HyperLink等。

  • 相关阅读:
    Codeforces 912 D. Fishes (贪心、bfs)
    Codeforces 908 D.New Year and Arbitrary Arrangement (概率&期望DP)
    HDU
    HDU
    POJ-2299 Ultra-QuickSort (树状数组)
    deque!
    HDU
    乘法逆元
    Codeforces 911D. Inversion Counting (数学、思维)
    Codeforces 909E. Coprocessor (拓扑、模拟)
  • 原文地址:https://www.cnblogs.com/caoshenghe/p/1684892.html
Copyright © 2020-2023  润新知