奇怪的WPF ListBox行为

时间:2010-04-17 15:23:29

标签: wpf listbox styles expander

我正在尝试将项目列表绑定到WPF中的ListBox。这些项目按一个值分组,每个组将位于Expander中。当我不使用任何自定义样式时,一切正常。但是,当我使用自定义样式(与未分组的项目和独立控件一起正常工作)时,绑定不会显示任何项目。下面是我正在执行的代码。任何想法为什么这些项目都不会出现在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>

1 个答案:

答案 0 :(得分:1)

ItemsPresenter控件模板中使用StackPanel代替ListBox(在TestStyles.xaml中)。