获取分隔符以填充剩余空间

时间:2011-06-12 23:15:38

标签: c# .net wpf wpf-controls styles

我确信这很简单,但我似乎无法弄明白。

我有一个ListBox来显示项目,这些项目与DataTemplate一起显示。我现在想要对这些项进行分组,因此根据制造商属性添加了一个组。这是在后面的代码中完成的。

ICollectionView view = CollectionViewSource.GetDefaultView(Items);
PropertyGroupDescription groups = new PropertyGroupDescription("Manufacturer");
view.GroupDescriptions.Add(groups);

我想让每个组都在扩展器中,因此可以隐藏它们。我通过查看MSDN上的GroupTemplates来实现这一点。这涉及到有一个扩展器,文本块,然后是一个分隔符来排除像Windows Vista / 7组中那样的额外空间。如下。

Windows 7 Groups

我遇到的问题是我无法让分隔符正确填满剩余空间。如果我使用MinWidth值,我的所有扩展器都具有相同的宽度。如果我使用{binding ActualWidth,ElementName = MyListBox},则分隔符太宽,因为它与包含它的控件一样宽。因此它将滚动条设置为可见,(见下面的屏幕截图)。如果我将宽度留空,则根本不会绘制分隔符。

我的直觉是,stackpanel应该扩展分离器以使用剩余的空间,但事实并非如此。所以我在下面的XamlCode中尝试了一个DockPanel,但这也失败了。通过使用合适的宽度来获取控件以填充剩余空间我还有一些其他问题,所以如果你能帮我解决这个问题,那就太棒了。

Current WPF ListBox-Group header Width Issue

我目前的WPF Xaml Markup。您需要添加元素才能显示内容。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<ScrollViewer VerticalScrollBarVisibility="Auto">
    <StackPanel x:Name="myStackPanel">
        <ListBox x:Name="MyListBox">
            <ListBox.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander IsExpanded="True">
                                            <Expander.Header>
                                                <DockPanel HorizontalAlignment="Stretch" 
                                                            VerticalAlignment="Stretch" 
                                                            Height="Auto" 
                                                            Width="{Binding ActualWidth, ElementName=MyListBox}"
                                                            Margin="10">
                                                    <TextBlock DockPanel.Dock="Left" Margin="0" FontSize="14" FontWeight="Bold" Foreground="Black" Text="{Binding Path=Name}"/>
                                                    <Separator DockPanel.Dock="Right" Margin="4,0,4,0"></Separator>
                                                </DockPanel>
                                            </Expander.Header>
                                            <ItemsPresenter Margin="5,0,0,0" />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListBox.GroupStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                   <!-- Data Template Here -->
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</ScrollViewer>

1 个答案:

答案 0 :(得分:1)

实际上并非易事,Expander的控件模板包含一个ToggleButton作为Header和一个ContentPresenter作为内容。问题是ToggleButton本身具有特殊的风格和特点。包含对齐硬编码的箭头的模板,默认值如下所示:

<Style x:Key="ExpanderDownHeaderStyle"
       TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Padding="{TemplateBinding Padding}">
                    <Grid Background="Transparent"
                          SnapsToDevicePixels="False">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="19"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <!-- ... -->

                        <!-- The HorizontalAlignment needs to be set to stretch here -->
                        <ContentPresenter Grid.Column="1"
                                          Margin="4,0,0,0"

                                          HorizontalAlignment="Left"

                                          VerticalAlignment="Center"
                                          SnapsToDevicePixels="True"
                                          RecognizesAccessKey="True"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                   <!-- ... -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

要让您的风格发挥作用,您需要修改默认的Expander模板(获取默认模板on MSDN - Default WPF Themes链接)。不好,但你真的没有多少选择。