WPF中的Template模板

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中同样可以使用触发器

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WPF(Windows Presentation Foundation)是一种用于构建Windows应用程序的技术,而UI template是一种在WPF用于创建可重复使用的用户界面样式和布局的机制。 WPF的UI template可以理解为一种定义了界面元素外观和样式的模板。通过使用UI template,我们可以很方便地将相同的界面元素样式应用于多个控件,从而实现界面的一致性和可重用性。 使用UI template的好处之一是简化了界面开发工作。开发人员只需要定义一次UI模板,然后可以在需要的地方直接应用这个模板,而不需要重新编写和调整样式。这在多个界面元素需要拥有相同外观的情况下特别有用。 另一个好处是提高了界面的灵活性。通过修改UI template,我们可以轻松地调整控件的样式、布局和属性,而不会破坏应用程序的整体结构。这样可以节省大量的时间和工作量,并且可以使界面更容易维护。 在WPF,UI template是由XAML语言定义的。通过使用XAML,开发人员可以以声明式的方式定义界面元素的外观和样式,而不需要编写繁琐的代码。这使得UI template的创建、修改和管理变得更加方便和直观。 总的来说,WPF的UI template是一种用于创建可重复使用的用户界面样式和布局的机制,它可以简化界面开发工作,提高界面的灵活性,并通过XAML语言实现了对界面的声明式定义。 ### 回答2: WPF(Windows Presentation Foundation)是微软推出的一种用于构建富客户端应用程序的技术。在WPF,UI模板(UI Template)是一种定义了控件外观和行为的重要组成部分。 UI模板被用于定义控件在界面上的外观,比如控件的背景、边框、字体样式、布局等。通过使用UI模板,我们可以根据应用程序的需求,自定义控件的外观,使之符合我们期望的样式和风格。这种灵活性使得WPF应用程序可以呈现出各种独特的界面设计。 UI模板的创建主要分为两个步骤:定义模板和应用模板。首先,我们需要根据需要定义一个模板,可以使用XAML(eXtensible Application Markup Language)来描述模板的结构和样式。模板可以包含多个可视元素和控件,并可以使用各种布局控件进行排列。其次,我们需要将定义好的模板应用到相应的控件上。在WPF,通过将控件的Template属性设置为我们定义的模板,就可以使控件采用我们自定义的样式。 使用UI模板可以为应用程序带来很多好处。首先,它使得应用程序的界面设计能够与众不同,使其与其他应用程序区别开来,提供独特的用户体验。其次,UI模板的灵活性使得我们可以方便地修改和调整控件的外观,而无需改变控件的内部逻辑。这种分离了界面与逻辑的设计思想有助于增强应用程序的可维护性和可扩展性。 总之,WPF的UI模板是一种非常强大的工具,可以帮助开发者定制出各种独特且具有个性化的界面,从而提升应用程序的用户体验。 ### 回答3: WPF (Windows Presentation Foundation)是一种用于创建丰富而功能强大的Windows桌面应用程序的框架。在WPF,UI模板是一种用于定义UI元素外观和行为的技术。 UI模板是一种XAML标记语言的结构,它描述了如何渲染和布局一个UI元素,从而决定了它的外观和行为。UI模板可以用于自定义各种控件,例如按钮、文本框、列表和窗体等。通过创建和应用UI模板,开发者可以完全控制和定制应用程序的外观和交互方式。 WPF的UI模板由多个元素组成,其包括容器元素、面板元素、控件元素和视觉元素等。容器元素用于包含和布局其他元素,面板元素用于定义元素的排列方式,控件元素用于添加交互和功能,视觉元素用于定义元素的外观。 开发者可以使用Visual Studio等工具创建和编辑UI模板。在模板,可以通过修改元素的属性、样式和模板绑定来改变元素的外观和行为。还可以通过添加触发器和动画等功能来实现交互效果。 通过使用UI模板,开发者可以根据自己的需求和设计要求来定制应用程序的外观。他们可以创建独特和个性化的用户界面,从而提供更好的用户体验。此外,UI模板还可以被多个控件共享,以实现统一的外观和风格。 总之,WPF的UI模板是一种强大的工具,可以让开发者自由定制和控制应用程序的外观和行为。通过使用UI模板,可以创建独特和个性化的用户界面,为用户提供更好的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值