【WPF】FrameworkElement 控件使用要点
控件一览
使用控件心得记录
1、ContentPresenter(内容 占位符)
ContentPresenter 来指定添加内容的位置。每个 ContentControl 类型的默认 ControlTemplate 中都有一个 ContentPresenter。ContentPresenter会从内容控件的content属性中获取值。
可以通过设置ContentSource属性或绑定到这些属性,让ContentPresenter属性从模板化父属性的其他属性中获取这些属性的值。
ContentPresenter的DataContext 等于模板的Content
具体用法如下:
<ControlTemplate TargetType="{x:Type HeaderedContentControl}"> <DockPanel> <ContentPresenter DockPanel.Dock="Top" ContentSource="Header" ContentTemplate="{TemplateBinding HeaderTemplate}" /> <ContentPresenter ContentSource="Content" ContentTemplate="{TemplateBinding ContentTemplate}" /> </DockPanel> </ControlTemplate>
2、HeaderedContentControl
带有标题的内容控件。有两个重要的属性Header和Content属性,Header属性和Content属性都Object类型。可以为header标题设置数据模板(HeaderTemplate) 如下:
<Setter Property="HeaderTemplate"> <Setter.Value> <DataTemplate> <Border Background="Blue" BorderBrush="LightGray" BorderThickness="1" CornerRadius="5" Margin="4" Padding="4" SnapsToDevicePixels="True" > <TextBlock FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" Text="{TemplateBinding Content}" /> <!--Content 绑定模板的ContentPresenter中的你内容,这边是header的数据模板,因此Content就是显示标题头--> </Border> </DataTemplate> </Setter.Value> </Setter> <!--不能获取焦点--> <Setter Property="IsTabStop" Value="False" />
3、Menu菜单栏
添加KeyboardNavigation.TabNavigation="None"附加属性控制 Tab导航的顺序。状态由KeyboardNavigationMode指定,一共由6种。设置MenuItem Header值记得添加“_”下滑线,用于TabNavigation。
<DockPanel> <DockPanel DockPanel.Dock="Top" KeyboardNavigation.TabNavigation="None"> <Menu KeyboardNavigation.TabNavigation="Cycle"> <MenuItem Header="_File"> <MenuItem Header="E_xit" Command="{Binding Path=CloseCommand}" /> </MenuItem> <MenuItem Header="_Edit" /> <MenuItem Header="_Options" /> <MenuItem Header="_Help" /> </Menu> </DockPanel> </DockPanel>
4、 ItemsControl
WPF中的列表式控件们派生自 ItemsControl类,自然也就继承了 ItemsSource这个属性。ItemsSource属性可以接收一个 IEnumerable 接口派生类的实例作为自己的值(所有可被达代遍历的集合都实现了这个接口,包括数组、List等)。
每个 ItemsControl的派生类都具有自己对应的条目容器( Item Container),例如, ListBox的条目容器是 ListBoxItem、 ComboBox的条目容器是ComboBoxItem. ItemsSource里存放的是一条一条的数据,要想把数据显示出来需要为它们穿上“外衣”,条目容器就起到数据外衣的作用。
怎样让每件数据外衣与它对应的数据条目关联起来呢?当然是依靠 Binding!只要我们为一个 ItemsControl对象设置了 ItemsSource属性值, ItemsControl对象就会自动迭代其中的数据元素、为每个数据元素准备一个条目容器,并使用 Binding在条目容器与数据元素之间建立起关联。。天生支持Grouping(分类)也就是说,启用了Grouping之后,会生成一些新的对象,GroupItem对象
5、ListView 列表
Template 为控件模板,整个控件的外观,比如加入边框,边距,背景等修改;
ItemsPanel:是子项的容器,可以是Stackpanel ,Wrappanel,VirtualStackPanel等 ,也可以控制子项的排列方式;作为集合元素承载容器,但集合控件本身却不负责呈现控件,那么这个任务就留给了子元素ItemsPresenter,其实用也很简单,只要把ItemsPresenter放在内部控件模板中,那么ItemsPresenter则会去检测父元素是否为集合控件,然后将ItemsPanel添加到其内部视觉树当中。
控制Item的显示方向 案例1:
<ListView.ItemsPanel > <ItemsPanelTemplate > <VirtualizingStackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListView.ItemsPanel>
案例2
给listbox的添加 uniform Panel
ItemContainerStyle 用于设置ItemControl的每一个Item的样式, 例如:listbox 的item的样式,listboxItem 样子如下设置;
ItemContainter条目容器:它的作用是将给每个Item添加一个UI外衣,这样item才能在显示在UI上。每一种条目控件(listbox comboBox等)都有自己对应的ItemContainer。ListBox的条目容器是ListBoxItem,Combox的条目容器是ComboBoxItem。
ItemTemplate:子项的数据模板,不能控制子项的显示和隐藏; 在做过滤的功能时候需要使用ItemContainerStyle ;如果ItemContainerStyle定义了Template属性,则ItemTemplate定义的无效;
ItemsPresenter (占位符): 在控件样式中标占一个区域,用于该区域用于呈现 ItemsControl中ItemsPanel 以及ItemsPanel 包含的内容。在项控件的模板中使用,用于指定要将ItemsPanel 定义的ItemsControl 添加到控件的可视化树中的什么位置。有时候控件并非维护本身逻辑,而是依赖于父子元素的,如了上诉的ContentPresenter,我们还有一个非常常用的ListBox控件,因为继承自ItemsControl,所以有一个ItemsPanel属性作为集合元素承载容器,但集合控件本身却不负责呈现控件,那么这个任务就留给了子元素ItemsPresenter,其实用也很简单,只要把ItemsPresenter放在内部模板中,那么ItemsPresenter则会去检测父元素是否为集合控件,然后将ItemsPanel添加到其内部视觉树当中
GridViewRowPresenter控件: 显示ListViewItem
GridViewHeaderRowPresenter: 显示ListView标题栏,可以结合GridViewRowPresenter控件来显示表格。
SelectionMode属性:确定用户一次可以选择多少项。 可以将属性设置为 Single (默认) 、 Multiple 或 Extended 。 下表描述了这些枚举值的行为。
AlternationCount:间隔显示颜色AlternationCount=2
6、TabControl
TabControl中的 ItemTemplate就是TabItem 设置头部标签,其他就是TabItem的内容,内容样式默认是空的默认值为 null。 ContentTemplate="{x:Null}" 所以可写可不写,
<TabControl IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" ItemTemplate="{DynamicResource ClosableTabItemTemplate}" ContentTemplate="{x:Null}" > </TabControl>
ContentTemplate可以直接设置可以可以直接设置在数据上
<DataTemplate DataType="{x:Type vm:CustomerViewModel}"> <vv:CustomerView/> </DataTemplate>