源项目地址:https://github.com/Microsoft/...
以下是把样例转换为简要说明,同时给出实际运行效果及关键代码:
-
AlternatingAppearanceOfItems子项颜色交替变换呈现
- 设置集合视图源记分组属性描述项
<local:Places x:Key="Places"/>
<!--Group the items by State.-->
<CollectionViewSource Source="{StaticResource Places}" x:Key="GroupedData">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="State"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
- 子项交替数索引对应颜色的转换器
<!--Returns a Brush for the header of a GroupItem.-->
<AlternationConverter x:Key="GroupHeaderBackgroundConverter">
<SolidColorBrush>LightBlue</SolidColorBrush>
<SolidColorBrush>LightSteelBlue</SolidColorBrush>
</AlternationConverter>
<!--Returns a Brush for a ListBoxItem.-->
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush>Silver</SolidColorBrush>
<SolidColorBrush>LightGray</SolidColorBrush>
<SolidColorBrush>GhostWhite</SolidColorBrush>
</AlternationConverter>
以上作为资源项。
- ListBox的分组样式、标题模板、数据模板 设置相对绑定,其中背景色绑定到GroupItem中的附加属性ItemsControl.AlternationIndex中索引转换出的颜色。
ps:AlternationCount 和 ItemsControl.AlternationIndex 属性允许您为两个或更多个交替项容器指定外观。例如,可以为 ItemsControl 中每隔两项的项目指定交替背景色。 ItemsControl.AlternationIndex 被分配给 ItemsControl 中的每一个容器。 ItemsControl.AlternationIndex 从 0 开始,增加到它为 AlternationCount 减 1 为止,然后从 0 重新开始。
<ListBox ItemsSource="{Binding Source={StaticResource GroupedData}}"
DisplayMemberPath="CityName" AlternationCount="3" Name="lb">
<ListBox.GroupStyle>
<!--Set alternating backgrounds on the header of each group.-->
<GroupStyle AlternationCount="2">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold"
Text="{Binding Path=Name}"
Background="{Binding
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type GroupItem}},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource
GroupHeaderBackgroundConverter}}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
- 设置ListBox的子项容器样式,子项背景色绑定到自身的附加属性ItemsControl.AlternationIndex转换出的颜色
<ListBox.ItemContainerStyle>
<!--Set alternating backgrounds on the items in the ListBox.-->
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
- TreeView的资源,包括数据模板、第三层背景色交替项转换器、第三分层数据模板;第二分层字体交替项转换器、第一、二分层数据模板资源
<Grid.Resources>
<local:ListLeagueList x:Key="MyTreeViewData"/>
<!--Returns alternating brushes.-->
<AlternationConverter x:Key="TeamsBackgroundConverter">
<SolidColorBrush>LimeGreen</SolidColorBrush>
<SolidColorBrush>SpringGreen</SolidColorBrush>
<SolidColorBrush>Chartreuse</SolidColorBrush>
</AlternationConverter>
<!--The DataTemplate used by TreeViewItems in the third level
of the TreeView.-->
<DataTemplate x:Key="Level3Data">
<TextBlock Text="{Binding Path=Name}"
Background="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type TreeViewItem}},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource TeamsBackgroundConverter}}"/>
</DataTemplate>
<!--Returns altnernating FontStyles.-->
<AlternationConverter x:Key="LeagueFontStyleConverter">
<FontStyle >Italic</FontStyle>
<FontStyle >Normal</FontStyle>
</AlternationConverter>
<!--The HierarchicalDataTemplate used by TreeViewItems
in the second level of the TreeView.-->
<HierarchicalDataTemplate x:Key="Level2Data"
ItemsSource="{Binding Path=Teams}"
ItemTemplate="{StaticResource Level3Data}"
AlternationCount="3">
<TextBlock Text="{Binding Path=Name}"
FontStyle="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type TreeViewItem}},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource LeagueFontStyleConverter}}"/>
</HierarchicalDataTemplate>
<!--The HierarchicalDataTemplate used by TreeViewItems
in the first level of the TreeView.-->
<HierarchicalDataTemplate x:Key="Level1Data"
ItemsSource="{Binding Path=Divisions}"
ItemTemplate="{StaticResource Level2Data}"
AlternationCount="2">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/>
</HierarchicalDataTemplate>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</Grid.Resources>
- 最后TreeView数据源绑定、子项模板绑定,后续分层模板根据ItemTemplate自动绑定
<TreeView ItemsSource="{Binding Source={StaticResource MyTreeViewData}}"
ItemTemplate="{StaticResource Level1Data}"/>
ContentControlStyle内容控件样式
- Label的样式及模板资源
<Grid.Resources>
<Style x:Key="ContentCtrl" TargetType="{x:Type ContentControl}">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Green"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<!--Keep the Ellipse a circle when ContentControl.Width
is set.-->
<Ellipse Width="{TemplateBinding Width}"
Height="{TemplateBinding Width}"
Fill="{TemplateBinding Background}"/>
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="Template1">
<TextBlock Text="{Binding}" FontSize="12" FontWeight="Bold" TextWrapping="Wrap" />
</DataTemplate>
</Grid.Resources>
- 界面xaml代码,Lablel为contentControl的ContentTemplate绑定到数据模板
<Label Margin="10, 10, 3, 3" Grid.Column="0" Grid.Row="2">
<ContentControl Width="75" Style="{StaticResource ContentCtrl}"
Content="Hello"/>
</Label>
<!--Put the ContentControl in a Label just to keep the margin and
Grid cruft out of the snippet.-->
<Label Margin="10, 10, 3, 3" Grid.Column="0" Grid.Row="3"
Background="LightBlue">
<ContentControl Name="contCtrl" ContentTemplate="{StaticResource Template1}"
Content="This is the content of the content control."/>
</Label>
EventTriggers事件触发器
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="300" Duration="0:0:1.5"
AccelerationRatio="0.10" DecelerationRatio="0.25"
Storyboard.TargetProperty="(Canvas.Width)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1.5"
AccelerationRatio="0.10" DecelerationRatio="0.25"
Storyboard.TargetProperty="(Canvas.Width)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
## FindingElementsInTemplates在模板中查找元素 ##
- 内容控件模板查找元素
private void ControlTemplateFindElement(object sender, RoutedEventArgs e)
{
// Finding the grid that is generated by the ControlTemplate of the Button
var gridInTemplate = (Grid) myButton1.Template.FindName("grid", myButton1);
// Do something to the ControlTemplate-generated grid
MessageBox.Show("The actual width of the grid in the ControlTemplate: "
+ gridInTemplate.GetValue(ActualWidthProperty));
}
- 模板控件中查找元素
private void DataTemplateFindElement(object sender, RoutedEventArgs e)
{
// Getting the currently selected ListBoxItem
// Note that the ListBox must have
// IsSynchronizedWithCurrentItem set to True for this to work
var myListBoxItem =
(ListBoxItem) (myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
// Getting the ContentPresenter of myListBoxItem
var myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
// Finding textBlock from the DataTemplate that is set on that ContentPresenter
var myDataTemplate = myContentPresenter.ContentTemplate;
var myTextBlock = (TextBlock) myDataTemplate.FindName("textBlock", myContentPresenter);
// Do something to the DataTemplate-generated TextBlock
MessageBox.Show("The text of the TextBlock of the selected list item: "
+ myTextBlock.Text);
}
private TChildItem FindVisualChild<TChildItem>(DependencyObject obj)
where TChildItem : DependencyObject
{
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var child = VisualTreeHelper.GetChild(obj, i);
if (child is TChildItem)
return (TChildItem) child;
var childOfChild = FindVisualChild<TChildItem>(child);
if (childOfChild != null)
return childOfChild;
}
return null;
}
其中查找父元素代码可简化为如下:
static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(T))
source = VisualTreeHelper.GetParent(source);
return source;
}
IntroToStylingAndTemplating介绍样式与模板
- ListBox样式
<!--Horizontal ListBox Control Template-->
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border CornerRadius="5" Background="{TemplateBinding ListBox.Background}">
<ScrollViewer HorizontalScrollBarVisibility="Auto" >
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center"
IsItemsHost="True"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
- ListBoxItem模板
<Style TargetType="ListBoxItem">
<Setter Property="Opacity" Value="0.5" />
<Setter Property="MaxHeight" Value="75" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Opacity" Value="1.0" />
</Trigger.Setters>
</Trigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:0.2"
Storyboard.TargetProperty="MaxHeight"
To="90" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:1"
Storyboard.TargetProperty="MaxHeight" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
- ListBox模板
<!--DataTemplate to display Photos as images
instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
<Border Margin="3">
<Image Source="{Binding Source}"/>
</Border>
</DataTemplate>
- ListBox绑定代码
ps:建议不用设置宽度,源码设置宽度造成滚动条随窗口变化显示不方便
<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
Background="Silver" Margin="10" SelectedIndex="0"/>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。