前言 对WPF来说ContentControl和ItemsControl是最重要的两个控件。 顾名思义,ItemsControl表示可用于呈现一组Item的控件。 大部分时候我们并不需要自定义ItemsControl,因为WPF提供了一大堆ItemsControl的派生类:HeaderedItemsControl、TreeView、Menu、StatusBar、ListBox 我以前写过一篇文章介绍如何模仿ItemsControl,并且博客园也已经很多文章深入介绍ItemsControl的原理,所以这篇文章只介绍简单的自定义ItemsControl知识,通过重写GetContainerForItemOverride 实现 确定好需要实现的ItemsControl后,通常我大致会使用三步完成这个ItemsControl: 定义ItemContainer 关联ItemContainer和ItemsControl 实现ItemsControl 如果ItemsControl的Items内容不是对应的子元素控件,ItemsControl会创建对应的子元素控件作为容器再把Item放进去。
以我的经验来说,通过继承ItemsControl来自定义模板化控件十分常见,了解ItemsControl对将来要自定义模板化控件十分有用。 这次用于讨论的SimpleItemsControl直接继承自Control,简单地模仿ItemsControl实现了它基本的功能,通过这个控件可以一窥ItemsControl的原理。 实际上ItemsControl的逻辑要复杂很多,这里只是个极端简化的版本。 到这一步一个简单的ItemsControl就完成了,总共只有100多行代码。 扩展ItemsControl 了解过ItemsControl的原理,或通过继承ItemsControl自定义控件就很简单了。譬如要实现这个功能:一个事件列表,自动为事件添加上触发的时间。 > </ItemsControl> 而是这样: <ItemsControl> <ItemsControl.Items> <local:ScoreModel Score="70"
我们在用到ItemsControl时,有时会用到分组,如ListBox,ListView,DataGrid。 WPF的ItemsControl可以实现分组,是依托于GroupStyle,以ListBox为例,他的分组效果图为: ? cv.GroupDescriptions.Add(new PropertyGroupDescription("UpTime")); 30 } 31 } 重点是28、29行,有了这两句,ListBox就能准确得分组显示了,其他ItemsControl
ItemsControl 相关知识点 ItemsControl 是 WPF 中最重要的集合控件基类,目前我见到的集合控件都是从这个类继承下来的。 ItemsControl.Items 属性 ItemsControl 中的属性 Items 是 ItemCollection 类型,而它是继承自 CollectionView!!! 也就是说,Items 其实是 ItemsSource 属性的视图集合类,我们可以通过这个属性来设置 ItemsControl 中集合的显示方案(Filter、Sorting、Grouping、Current 发现一篇不错的文章:《ItemsControl: A to Z》
用 ItemsControl 第三种方案是用 ItemsControl 实现,这个方案虽然会绕些弯路,但胜在够有趣,而且能扩展其它玩法。 首先,因为 string 是个集合,其实它可以用作 ItemsControl 的 ItemsSource。 TextBlock 上: <ItemsControl ItemsSource="{TemplateBinding Content}" > <ItemsControl.ItemsPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 接下来,为了让每个字符显示不同的颜色,需要实现一个 Collection 嵌套 ItemsControl,就可以做出下面这种效果: 又或者,这次不玩递增,玩随机。
d:DesignHeight="290" d:DesignWidth="180"> <Grid name="gridMain"> <ItemsControl > <ControlTemplate TargetType="<em>ItemsControl</em>"> > <ItemsControl.ItemTemplate> > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> > </ItemsControl> </Grid> </UserControl> ScrollViewer在控件模版中,ScrollViewer
--<ItemsControl ItemsSource="{Binding NestGroups}"> 18 <ItemsControl.ItemsPanel> 19 > 23 <ItemsControl.ItemTemplate> 24 <DataTemplate>--> 25 <Border > 35 <ItemsControl.ItemContainerStyle> 36 <Style TargetType > 80 </ItemsControl> 81 </Grid> 82 </Border> 83 <! --</DataTemplate> 84 </ItemsControl.ItemTemplate> 85 </ItemsControl>--> 86 87
object _oldClip; } } 静态容器 StackPanel 行列布局不能换行 WrapPanel 行列布局能换行 Grid 网格布局 DockPanel 东西南北中布局 动态容器 ItemsControl ListBox ListView DataGrid ItemsControl、ListBox和ListView ListView继承于ListBox,ListBox继承于ItemsControl 相同点: 这三个控件都是列表型控件,可以进行列表绑定(ItemsSource); 这三个控件均使用ItemsPresenter来展示列表信息; 不同点: ListBox 继承于ItemsControl ,增加了一个Selector对象,ItemsControl中的Item是不支持选择的。 ItemsControl是不包含水平和垂直方向的滚动条的。ListBox和ListView有水平和垂直方向滚动条。
如果你试图给 WPF 的 ItemsControl 加入自动化识别,或者支持无障碍使用,会发现 ItemsControl 内的元素如果进行了分组,则只能识别到组而不能识别到元素本身。 现象 现在,我们在 ItemsControl 的内部放几个按钮并进行分组。 The fixed version of the ItemsControl. public class FixedItemsControl : ItemsControl { protected itemsControl = ItemsControl.ItemsControlFromItemContainer(Owner); if (itemsControl ! 可以发现,它单独对 ItemsControl 判断了我们本文一开始所说的开关。
查找ItemsControl.ItemTemplate的引用会发现一个值得注意的方法ItemsControl.PrepareContainerForItemOverride:
复制代码
//ItemsControl 如果是element也是ItemsControl,这意味着一个ItemsControl的ItemTemplate里又嵌套了一个ItemsControl,这时就把父控件的ItemTemplate传递给子控件的 查看引用可以发现ItemsControl.PrepareItemContainer()方法调用了这个方法,其代码如下:
复制代码
//ItemsControl**
///
思路:用两个ItemsControl来表示横向列名和纵向列名,中间部分用两个itemsControl来生成数据主内容,因为策略要保证中间部分宽度 跟顶部宽度一致,所以中间数据表线竖后横。 > </ItemsControl> </Canvas> </Border> <Border <ItemsControl ItemsSource="{Binding Children}"> <ItemsControl.ItemsPanel </ItemsControl.ItemTemplate> <ItemsControl.RenderTransform> > </ItemsControl> </Canvas> </Border> <!
使用 CirclePanel 实现 既然要用 ItemsControl,那首先要有个集合作为它的 ItemsSource。 ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate > </ItemsControl> </DataTemplate> </ContentControl.ContentTemplate> </ContentControl > 这样 UI 上就会重复创建 12 个 Rectangle,然后设置 ItemsControl 的 ItemsPanel,让这些 Rectangle 按着圆形布局。 这里我使用了 HandyControl 的 CirclePanel,这个 Panel 用起来十分简单,它会自动将 Children 在圆形上等距分布: <ItemsControl.ItemsPanel>
1.3 玩玩彩虹文字及动画 用 ItemsControl 拆分文字实现彩虹文字是一个很好玩的方案,因为可以对每个文字做不同的变形和动画,实现很多种玩法。 首先,因为 string 是个集合,其实它可以用作 ItemsControl 的 ItemsSource。 </ContentControl.Template> </ContentControl> 然后设置 ItemsControl 的 ItemsPanel,让内容横向排列;设置 DataTemplate, 让拆分后的字符显示在 TextBlock 上: <ItemsControl ItemsSource="{TemplateBinding Content}" > <ItemsControl.ItemsPanel </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 接下来,为了让每个字符显示不同的颜色,需要实现一个 Collection
前言 ItemsControl和ListBox都可以用做列表,既然是列表,那么我们怎样获取列表点击的项呢。 ListBox点击列表项后就不能再触发点击事件,而ItemsControl压根就没有选中项,那么怎样处理呢? o = toolbar_list.SelectedItem; if (o == null) return; MessageBox.Show(o.ToString()); } ItemsControl StackPanel> </Button.Content> </Button> </DataTemplate> </Window.Resources> <ItemsControl ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.Row="1" Background="#f3f3f3" BorderThickness="0"> </ItemsControl
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(<em>ItemsControl</em>.AlternationIndex </ListView> 获取当前列表项,使用{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(<em>ItemsControl</em>.AlternationIndex <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(ItemsControl.AlternationIndex
Data() { DataValue = 120 }); this.DataContext = data; } 在XAML文件中添加ItemsControl <ItemsControl ItemsSource="{Binding}"></ItemsControl> 为其创建ItemsPanel模板,如下。 <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> > </ItemsControl> 现在,为了正确地表示数据,创建DataTemplate,如下所示。 <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(<em>ItemsControl</em>.AlternationIndex 获取当前列表项,使用{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(<em>ItemsControl</em>.AlternationIndex <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(ItemsControl.AlternationIndex
--tip显示区--> <ItemsControl x:Name="itemsTip" Canvas.Top="-21" Canvas.Left="0" Visibility="Collapsed"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate > </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Rectangle Fill="{Binding Name}" Width="20" Height="20" Margin="0,0,1,0" MouseLeftButtonDown="ChangeColor"/> </DataTemplate> </ItemsControl.ItemTemplate > </ItemsControl> </Canvas> </Grid> </UserControl> 后端代码: using System.Collections.Generic; using
ScrollViewer Name="ModuleScrollViewer" VerticalScrollBarVisibility="Auto"> <ItemsControl CornerRadius="12" ItemsSource="{Binding Modules}" Margin="2"> <ItemsControl.ItemTemplate > </ItemsControl> </ScrollViewer> ItemsSource="{Binding Messages}" CornerRadius="12" Margin="2"> <ItemsControl.ItemTemplate > </ItemsControl> </ScrollViewer>
Window.Resources> 页面 <Grid> <ScrollViewer Name="TjSv" Padding="200 -20 200 20"> <ItemsControl ItemsSource="{Binding TjList}" ItemTemplate="{StaticResource TjItemDt}"> </ItemsControl