【问题标题】:Getting a separator to fill up the remaining space获取分隔符以填充剩余空间
【发布时间】:2011-09-13 14:22:19
【问题描述】:

我确信这很简单,但我似乎无法弄清楚。

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

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

我想将每个组都放在一个扩展器中,这样它们就可以隐藏起来。我通过查看 MSDN 上的 GroupTemplates 来完成这项工作,这涉及到有一个扩展器、文本块,然后是一个分隔符来排除 Windows Vista/7 组中的额外空间。如下。

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

我的直觉是堆栈面板应该扩展分隔符以使用剩余空间,但它没有。所以我在下面的 XamlCode 中尝试了一个 DockPanel,但这也失败了。通过使用合适的宽度让控件填充剩余空间时,我还有一些其他问题,所以如果你能帮我解决这个问题,那就太好了。

我当前的 WPF Xaml 标记。您将需要添加元素以使其显示某些内容。

<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>

【问题讨论】:

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


    【解决方案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 链接)。不好,但你真的别无选择。

    【讨论】:

    • 我认为这会很简单。我不想修改扩展器本身。而只是在它的侧面添加了一个分隔符。今晚我会尝试阅读 MSDN 链接,并尝试将一些代码移到 Expander 标头之外,看看它是否比我目前尝试的更容易。
    • 我发现这个 stackoverflow 问题也很有用 - stackoverflow.com/questions/661503/…
    猜你喜欢
    • 2019-03-18
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多