Strange WPF ListBox Behavior
Posted
by uncle-harvey
on Stack Overflow
See other posts from Stack Overflow
or by uncle-harvey
Published on 2010-04-17T15:23:28Z
Indexed on
2010/04/25
13:03 UTC
Read the original article
Hit count: 470
I’m trying to bind a List of items to a listbox in WPF. The items are grouped by one value and each group is to be housed in an expander. Everything works fine when I don’t use any custom styles. However, when I use custom styles (which work properly with non-grouped items and as independent controls) the binding doesn’t display any items. Below is the code I’m executing. Any ideas why the items won’t show up in the Expander?
Test.xaml:
<Window x:Class="Glossy.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\TestStyles.xaml"/>
<ResourceDictionary>
<Style x:Key="ContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding}" IsExpanded="True">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ListBox x:Name="TestList">
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/>
</ListBox.GroupStyle>
</ListBox>
</Grid>
Test.xaml.cs:
public partial class Test : Window
{
private List<Contact> _ContactItems;
public List<Contact> ContactItems
{
get { return _ContactItems; }
set { _ContactItems = value; }
}
public Test()
{
InitializeComponent();
ContactItems = new List<Contact>();
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 1";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 2";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 3";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 10";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 11";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "ABC";
ContactItems.Last().Name = "Contact 12";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "RST";
ContactItems.Last().Name = "Contact 7";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "RST";
ContactItems.Last().Name = "Contact 8";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "RST";
ContactItems.Last().Name = "Contact 9";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "XYZ";
ContactItems.Last().Name = "Contact 4";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "XYZ";
ContactItems.Last().Name = "Contact 5";
ContactItems.Add(new Contact());
ContactItems.Last().CompanyName = "XYZ";
ContactItems.Last().Name = "Contact 6";
ICollectionView view = CollectionViewSource.GetDefaultView(ContactItems);
view.GroupDescriptions.Add(new PropertyGroupDescription("CompanyName"));
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
TestList.ItemsSource = view;
}
}
public class Contact
{
public string CompanyName { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
TestStyles.xaml:
<Style TargetType="{x:Type ListBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="95"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Grid Background="Black">
<Rectangle VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Fill="White">
<Rectangle.OpacityMask>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Geometry="M65.5,33 L537.5,35 537.5,274.5 C536.5,81 119.5,177 66.5,92" Brush="#11444444">
<GeometryDrawing.Pen>
<Pen Brush="Transparent"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.OpacityMask>
</Rectangle>
<Border Name="Border"
Background="Transparent"
BorderBrush="Gray"
BorderThickness="1"
CornerRadius="2">
<ScrollViewer Margin="0" Focusable="false">
<StackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Gray" />
<Setter TargetName="Border" Property="BorderBrush" Value="DimGray" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Margin" Value="3,1,3,1"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="Gray"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButton">
<Border Name="Border"
CornerRadius="2,0,0,0"
Background="Transparent"
BorderBrush="LightGray"
BorderThickness="0,0,1,0">
<Path Name="Arrow"
Fill="Blue"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="Gray" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Black" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Arrow" Property="Data" Value="M 0 4 L 4 0 L 8 4 Z" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="DimGray" />
<Setter TargetName="Border" Property="BorderBrush" Value="DimGray" />
<Setter Property="Foreground" Value="LightGray"/>
<Setter TargetName="Arrow" Property="Fill" Value="LightBlue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="ContentRow" Height="0"/>
</Grid.RowDefinitions>
<Border Name="Border"
Grid.Row="0"
Background="Black"
BorderBrush="DimGray"
BorderThickness="1"
Cursor="Hand"
CornerRadius="2,2,0,0" >
<Grid HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ExpanderToggleButton}"
Background="Black" />
<Label Grid.Column="1"
FontSize="14"
FontWeight="Normal"
Margin="0"
VerticalAlignment="Top"
Foreground="White"
FontFamily="Verdana">
<ContentPresenter Grid.Column="1"
Margin="4,3,0,0"
HorizontalAlignment="Left"
ContentSource="Header"
RecognizesAccessKey="True" />
</Label>
</Grid>
</Border>
<Border Name="Content"
Background="Black"
BorderBrush="DimGray"
BorderThickness="1,0,1,1"
Grid.Row="1"
CornerRadius="0,0,2,2" >
<Grid Background="Black">
<Rectangle VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Fill="White">
<Rectangle.OpacityMask>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Geometry="M65.5,33 L537.5,35 537.5,274.5 C536.5,81 119.5,177 66.5,92" Brush="#11444444">
<GeometryDrawing.Pen>
<Pen Brush="Transparent"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.OpacityMask>
</Rectangle>
<ContentPresenter Margin="4" />
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content,Path=DesiredHeight}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Gray" />
<Setter TargetName="Border" Property="BorderBrush" Value="DimGray" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
© Stack Overflow or respective owner