WPF中的Template模板

来源:互联网 发布:揭秘黑马程序员骗局 编辑:程序博客网 时间:2024/05/21 10:28

d## WPF中的模板Template ##
WPF中通过引入模板将数据和算法的内容和形式解耦
ControlTemplate 是算法的内容的表现形式,决定了控件长成什么样子,让程序员在控件原有的内部逻辑基础上扩展自己的逻辑
DataTemplate 是数据的内容的表现形式,数据显示成什么形式,外观

DataTemplate
常用在三处:
ContentControl的ContentTemplate属性,
ItemsControl的ItemTemplate属性,
GridViewColumn的CellTemplate属性

public class AutomakerToLogoPathConverter:IValueConverter{    public object Convert(object value,Type targetType,object parameter,CultureInfo culture){        string uriStr = string.Format(@"/Resources/Logos/{0}.png",(stringvalue));        return new BitmapImage(new Uri(uriStr,UriKind.Relative));    }    publiuc ConvertBack(object value,Type targetType,object parameter,CultureInfo culture){    throw new NotImplementedException();    }}public class NameToPhotoPathConverter:IValueConverter{    public object Convert(object value,Type targetType,object parameter,CultureInfo culture){        string uriStr = string.Format(@"/Resources/Images/{0}.png",(stringvalue));        return new BitmapImage(new Uri(uriStr,UriKind.Relative));    }    publiuc ConvertBack(object value,Type targetType,object parameter,CultureInfo culture){    throw new NotImplementedException();    }}...<Window    ...>    <Window.Resources>        <local:AutomakerToLogoPathConverter x:Key = "a2l"/>        <local:NameToPhotoPathConverter x:Key = "n2p"/>        <DataTemplate x:Key = "carDetailViewTemplate"            <Stackpanel>                ....                <Image Width = "400" Height = "250"                    Source = "{Binding Name,Converter{StaticResource n2p}}"/>                ...            </Stackpanel>            ...        </DataTemplate>         <DataTemplate x:Key = "carListViewTemplate"            ...        </DataTemplate>     </Window.Resources>    <StackPanel Orientation = "Horizontal" Margin = "5">        <UserControl ContentTemplate = "{StaticResource carDetailViewTemplate}"                     Content = "{Binding SelectedItem,ElementName = listBoxCars}"/>        <ListBox x:Name = "listBoxCars" Width = "180" margin= “50”                 ItemTemplate = "{StaticResource0 carListViewTemplate}"/>    </StackPanel ></Window>    ...private void InitialCarList(){    List<Car> carList = new List<Car>(){        new Car{Automaker = "tfewaf",Name = "fase",Year = "1964",TopSpeed = "131"},        new Car{Automaker = "tfewaf",Name = "fase",Year = "1964",TopSpeed = "131"},        new Car{Automaker = "tfewaf",Name = "fase",Year = "1964",TopSpeed = "131"},        new Car{Automaker = "tfewaf",Name = "fase",Year = "1964",TopSpeed = "131"},        new Car{Automaker = "tfewaf",Name = "fase",Year = "1964",TopSpeed = "131"}    }    this.lisrBoxCars.ItemsSource = carList;}

ControlTemplate
用处:
更换ControlTemplate改变控件外观,使之具有更优的用户体验及外观。
借助ControlTemplate让程序员和设计师并行工作。

打开Blend开始编辑
组件上右键,编辑模板,编辑副本

ControlTemplate可以放在三个地方Application的资源字典中,界面元素的资源字典中,外部XMAL文件中。

ControlTemplate 在Blend中通过可视化界面编辑模板即可。

ControlTemplate 和DataTemplate 的区别

ControlTemplate :决定控件的外观
DataTemplate : 决定数据的外观。与具体数据相关的控件,比如需要Binding数据的控件,数据转换Converter。
DataTemplate 是 ControlTemplate 的一颗子树。

如何找控件树根:
控件的TemplateParent属性的值就是应用了模板的控件。
控件的TemplateBinding的数据源就是应用类这个模板的目标控件。

Template的应用
1. 逐个设置控件的Template/ContentTemplate/ItemsTemplate/CellTemplate 等属性。
2. 把Template应用在某个类型的控件或数据上。

例:

<Window.Resources>    <DataTemplate DataType = "{x:Type local:Unit}">        <StackPanel>            <TextBlock Text = "{Binding Price}"/>        </StackPanel>    </DataTemplate></Window.Resources>    ...public class Unit{    public int Price{get;set;}    public string Year{get;set;}}

DataTemplate的目标数据类型和ListBox的条目类型都是Unit
DataTemplate会自动加载到所有Unit类型对象上

<Window.Resources>    <DataTemplate DataType = "Unit">        <StackPanel>            <TextBlock Text = "{Binding XPath = @Price}"/>            <TextBlock Text = "{Binding XPath = @Year}"/>        </StackPanel>    </DataTemplate>    ...    <XmlDataProvider x:Key = "ds" XPath="Unites/Unit">        <x:XData>            <Units xmlns = "">                <Unit Year = "2001" Price = "100"/>                ...            </Units>        </x:XData>      </XmlDataProvider></Window.Resources>    ...    <ListBox ItemSource="{Binding Source = {StaticResource de}}"/>    <ComboBox ItemSource="{Binding Source = {StaticResource de}}"/>

将XML作为数据源

<HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath = Student}">    <TextBlock Text="{Binding XPath=@Name}"</HierarchicalDataTemplate>

找到Template中的组件

ControlTemplate

TextBox tb = this.uc.Template.FindName("textBox1",this.uc) as Textbox;tb.Text="Hello Wpf";StackPanel sp = tb.Parent as StackPanel;(sp.children[1] as TextBox).Text = "Hello Template";(sp.children[1] as TextBox).Text = "Hello Template";

DataTemplate
例1:

<ContentPresenter ContentTemplate="{StaticResource stuDT}"/>...TextBox tb = this.uc.ContentTemplate.FindName("textBox1",this.cp) as Textbox;MessageBox.Show(tb.Text);

例2:

private void TextBoxNAme_GotFocus(object sender,RoutedEventArgs e){    TextBox tb = e.OriginalSource as TextBox;//获取事件发起的源头    ContentPresenter cp = tb.TemplatedParent as ContentPresenter;//获取模板目标    Student stu = cp.Content as Student;//获取业务逻辑    this.listViewStudent.SelectedItem = stu;//设置ListView的选中项    //访问界面元素    ListViewItem lvi = this.listViewStudent.                    ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;    CheckBox chb = this.FindVisualChild<CheckBox>(lvi);    MessageBox.Show(chb.Name);}private ChildType FindVisualChild<ChildType>(DependencyObject obj)where ChildType:DependencyObject {    for(int i=0;i<VisualTreeHelper.GetChildrenCount(obj);i++){        DependencyObject  child = VisualTreeHelper.Get(obj,i);        if(child !=null && child is ChildType){            return child as ChildType;        }else{            ChildType childOfChild = FindVisualChild<ChildType>(child);            if(childOfChild !=null) return childOfChild ;        }    }    return null;}

Style样式

style包括setter和trigger,分别表示控件的静态外观风格和行为风格。

Setter 设置属性值
例:

<Setter Property = "FontSize" Value="24"/><Setter Property = "FontStyle" Value="Italic"/><Setter Property = "Template" Value="ControlTemplate"/>

Trigger 触发器
一般由用户操作触发。
事件触发型EventTrigger,数据变化触发型Trigger/DataTrigger,多条件触发型MultiTrigger/MultiDataTrigger。

1.基本触发器
Property 检测的属性,Value 触发的条件
Setters触发后执行的动作,比如换肤
例:

<Style Targettype = "CheckBox">    <Style.Triggers>        <Trigger Property = "IsChecked" Value="true">            <Trigger.Setters>                <Setter Property="FontSize" value="20"/>                <Setter Property="Foreground" value="Orange"/>            </Trigger.Setters>        </Trigger>    </Style.Triggers></Style>    ...<StackPanle>    <CheckBox Content="check1"/>    <CheckBox Content="check2"/>    <CheckBox Content="check3"/>    <CheckBox Content="check4"/></StackPanle>

2.MultiTrigger 多条件同时成立才触发,比Trigger多一个Conditions属性,需要成立的条件就存储在此集合中。

...<MultiTrigger.Conditions>    <Coadition Property="isChecked" Value="true"/>    <Coadition Property="Content" Value="Hello"/></MultiTrigger.Conditions>...

3.DataTrigger Binding属性的值与Value的值一样触发

<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=Text.Length,Converter={StaticResource cvt2r}}"Value="false">//在cvtr中进行判断操作    <Setter.../>    <Setter.../>    <Setter.../></DataTrigger>

4.MultiDataTrigger 多数据条件同时满足时触发

...<MultiDataTrigger>    <MultiDataTrigger.Conditions>        <Condition Binding="{Binding Path=ID}" Value="2"/>        <Condition Binding="{Binding Path=Name}" Value="Tom"/>    </MultiDataTrigger.Conditions>    <MultiDataTrigger.Setters>    ...    </MultiDataTrigger.Setters></MultiDataTrigger>

5.EventTrigger
事件触发,比较特殊。它由事件触发,而且触发后不是应用一组setter而是执行一段动画。
UI层的动画效果往往与EventTrigger关联。
例如Button的MouseEnter和MouseLeave的事件触发器。

例:

<EventTrigger RoutedEvent = "MouseEnter">    <BeginStoryboard>        <Storyboard>            <DoubleAnimation To="150" Duration= "0:0:0.2" Storyboard.TargetProperty="Width"/>            <DoubleAnimation To="150" Duration= "0:0:0.2" Storyboard.TargetProperty="Width"/>        </Storyboard>    </BeginStoryboard></EventTrigger>

不仅Style中可以使用触发器,Template中同样可以使用触发器

原创粉丝点击