【问题标题】:Margin difference in nested ListBox with DataTemplates嵌套 ListBox 与 DataTemplates 的边距差异
【发布时间】:2014-04-16 09:30:26
【问题描述】:

我的列表框有问题。我已经编写了几个在 ListBox 中使用的 DataTemplate。其中每一个都包含一个网格,并且可能包含一个嵌套的 ListBox,具体取决于项目。 我的问题是:这些嵌套列表框的高度似乎与根列表框的高度不同。此外,上面的元素有时似乎有一个像素边距。

有没有人也遇到过这个问题,也许已经解决了?

XAML 代码:

         <!-- Template for SubData-Items -->
         <DataTemplate x:Key="DataTemplate">

            <Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999" Background="Violet">

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
                    <ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
                </Grid.RowDefinitions>

                <TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
                <Line Grid.ColumnSpan="999" Stroke="Black" X1="0" X2="{Binding ElementName=baseGrid, Path=ActualWidth, Mode=OneWay}" Y1="0" Y2="0" VerticalAlignment="Bottom" />

            </Grid>

        </DataTemplate>

        <!-- Template for Items -->
        <DataTemplate x:Key="GroupDataTemplate">

            <Grid Grid.ColumnSpan="999" Background="Blue">

                <Grid.RowDefinitions>
                    <RowDefinition Height="{Binding ElementName=Gantt, Path=GridRowHeight}" />
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>

                <Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999">

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
                        <ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>
                        <RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
                    </Grid.RowDefinitions>

                    <TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />

                </Grid>

                <Grid x:Name="expandedGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999">

                    <ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"                                                                                
                                    VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="0,0,2,0"
                                    ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />

                </Grid>

            </Grid>

        </DataTemplate>

   <!-- Grid with ListBox -->
   <Grid>

        <Grid.RowDefinitions>
            <RowDefinition x:Name="Row0" Height="34"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="Col0" Width="25" />
            <ColumnDefinition x:Name="Col1" Width="*" />
        </Grid.ColumnDefinitions>

        <ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999" ItemsSource="{Binding ItemSource, Mode=OneWay}"
            ItemTemplate="{StaticResource GroupDataTemplate}"
            VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto"               
            ScrollViewer.CanContentScroll="true"
            ScrollViewer.IsDeferredScrollingEnabled="False"
            ScrollViewer.HorizontalScrollBarVisibility="Disabled"
            ScrollViewer.VerticalScrollBarVisibility="Disabled"
            FontSize="10" />

    </Grid>

【问题讨论】:

  • 您好,请使用 XAML 更新您的问题,以便我们了解您是如何嵌套所有内容的。
  • 在您的子项目 ListBox DataTemplate 中,您将 RowHeight 绑定到“带有 ListBox 的网格”中的行的高度,我相当确定这不会起作用,但更重要的是我不确定你想做这个!通过将嵌套的 ListBox 设置为与父 ListBox 相同的大小只会导致父 ListBox 增长。你到底想达到什么目的?如果它正在改变边距,您可以尝试使用负值来删除您看到的额外的一个像素。
  • 我试图实现的是列表中的每一行都具有相同的高度,因为它必须适合它右侧的视觉元素,该元素具有垂直绘制的线条。我也尝试给它们一个负边距,但这只会导致网格使上面的线不可见。
  • 如果您有嵌套的数据模板,您应该使用HierarchicalDataTemplate 而不是常规的DataTemplate。另外,为什么要通过绑定设置行和列的宽度和高度?为什么不用SharedSizeGroup,你用过吗?

标签: c# wpf listbox margin datatemplate


【解决方案1】:

qqbenq 给出了一个很好的解决方案。这是另一种方法。

ListBox 和 ListBoxItem 的控件模板在其边框内有填充。值得庆幸的是 ListBoxItem 边框的填充可以通过如下样式控制:

    <Style
        TargetType="ListBoxItem">
        <Setter
            Property="Padding"
            Value="0" />
    </Style>

但不幸的是,对于 ListBox ,您必须使用其所有详细信息覆盖默认模板,以更改其内部边框的硬编码填充,如下所示:

    <Style
        TargetType="ListBox">
        <Setter
            Property="Template">
            <Setter.Value>
                <ControlTemplate
                    TargetType="{x:Type ListBox}">
                    <Border
                        x:Name="Bd"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        Padding="0"
                        SnapsToDevicePixels="true">
                        <ScrollViewer
                            Focusable="false"
                            Padding="{TemplateBinding Padding}">
                            <ItemsPresenter
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger
                            Property="IsEnabled"
                            Value="false">
                            <Setter
                                Property="Background"
                                TargetName="Bd"
                                Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                        </Trigger>
                        <Trigger
                            Property="IsGrouping"
                            Value="true">
                            <Setter
                                Property="ScrollViewer.CanContentScroll"
                                Value="false" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

最后一点:删除您在 xaml 中添加的边距。

解决方案完成

【讨论】:

    【解决方案2】:

    将 Margin="-2,0,0,0" 和 Padding="-1" 添加到名为 ListBox 的“LBMaGruppen”中。

    <ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"                                                                                
                                    VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="-2,0,0,0" Padding="-1"
                                    ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
    

    另外,“根”元素的高度绑定到 {Binding ElementName=Gantt, Path=GridRowHeight},而“子”元素的高度绑定到 {Binding ElementName=Row0, Path=Height},所以这一定会导致差异.

    【讨论】:

    • +1 和 Bounty 以获得简单而干净的解决方案。没想到设置padding-property。谢谢
    【解决方案3】:

    您的所有列表框似乎都设置了自动高度。您可以尝试将高度设置为特定大小。编辑:我看到你已经有了 ScrollViewer 设置。我认为将框的高度设置为特定大小而不是 auto 会满足您的要求。

    关于元素之间的填充,请参阅ListBox.ItemContainerSyle,它应该允许您设置元素之间的边距。

    【讨论】:

    • 将高度设置为特定值不是解决方案,因为每个项目都可以有 x 个子项目。我以前不知道。滚动查看器只能出现在根 ListBox 中,因为其中的行必须适合它的可视元素。玩弄 margin 属性也没有用。
    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 2017-02-07
    • 2011-08-30
    • 2011-03-25
    • 2013-03-26
    相关资源
    最近更新 更多