WPF - Group分组对ListBox等列表样式的约束
在做WPF主題支持時,出現一個分組引起的莫名錯誤,可是折騰了我一番。在沒有使用樣式時,列表分組很正常,使用了別人寫的ListBox列表樣式后,發現GroupItem分組區沒有內容,是空的,本篇把這一問題的解決過程給大家說一下,做主題時可以注意分組對列表樣式的限制了。
ListBox增加分組
WPF為ItemsControl提供很多的樣式擴展,要想實現列表分組也很簡單,只需要做以下幾步就可以了:
代碼 <Style x:Key="GroupContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,10,0">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount, StringFormat=(共{0}條)}"/>
</StackPanel>
<Line Grid.Column="1" SnapsToDevicePixels="true" X1="0" X2="1" Stretch="Fill" StrokeThickness="1"/>
</Grid>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
GroupStyle gs = new GroupStyle();
gs.ContainerStyle = Application.Current.TryFindResource("GroupContainerStyle") as Style;
lbModule.GroupStyle.Add(gs);
給數據增加分組
代碼 <UserControl.Resources><CollectionViewSource Source="{x:Static oea:ApplicationModel.DefaultBusinessObjectInfos}" x:Key="cvs">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Catalog" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
使用ListBox樣式后
用了別人的一個ListBox樣式文件,樣式如下:
代碼 <Style TargetType="{x:Type ListBox}"><Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource PrimaryColor}" Offset="0" />
<GradientStop Color="{DynamicResource SecondaryColor}" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1" CornerRadius="4,4,4,4">
<Grid>
<ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false" x:Name="scrollViewer">
<StackPanel Margin="2" IsItemsHost="true"/>
<!--<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />-->
</ScrollViewer>
<Border CornerRadius="4,4,4,4" Visibility="Collapsed" x:Name="border" Margin="-2,-2,-2,-2">
<Border.Background>
<SolidColorBrush Color="{DynamicResource DisabledColor}"/>
</Border.Background>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" TargetName="border" Value="Visible"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用完之后運行發現界面不對,點擊分組標題后列表內容沒有顯示???
查找原因
自己想了一下,原因不明,無奈自己對WPF實現只了解一點,于是網上搜索ItemsPresenter empty,找到第一條網頁ItemsPresenter + ItemsPanelTemplate vs Panel marked with IsItemsHost,進去后發現他提出了一個問題,就是在分組時如何取ItemsPresenter,發現Reflector工具可以看到以下代碼:
代碼internal static ItemsPresenter FromGroupItem(GroupItem groupItem){
if (groupItem == null)
{
return null;
}
Visual parent = VisualTreeHelper.GetParent(groupItem) as Visual;
if (parent == null)
{
return null;
}
return (VisualTreeHelper.GetParent(parent) as ItemsPresenter);
}
?
這個帖子上面也解釋了為什么這么設計,我就不再重復了,原來在分組時對控件樣式有要求,那就是控件樣式必須存在ItemsPresenter。
確認原因
使用《WPF - Visual調試工具Snoop》工具查看一下,發現GroupItem下的ItemsPresenter是空的
切換回不使用樣式再看看,發現在GroupItem之上有一個ItemsPresenter,而應用上面樣式之后就沒有了,果然就是樣式文件的控件模板缺少ItemsPresenter的原因。
解決問題
原因知道了,解決問題也就非常簡單了,修改樣式表,主要就是把
<StackPanel Margin="2" IsItemsHost="true"/>
該為
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
修改后再次運行,界面正確,如下:
?
更多內容: 開源信息系統開發平臺之OpenExpressApp框架.pdf
?
?
歡迎轉載,轉載請注明:轉載自周金根 [ http://zhoujg.cnblogs.com/ ]
總結
以上是生活随笔為你收集整理的WPF - Group分组对ListBox等列表样式的约束的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速搭建ELK,以及简单故障处理
- 下一篇: java操作大文件复制