【问题标题】:WPF 4.0 - Datagrid column widths & margins with groupingWPF 4.0 - 带有分组的 Datagrid 列宽和边距
【发布时间】:2014-07-06 08:14:54
【问题描述】:

我遇到了一个与 WPF 数据网格中的分组相关的问题,在使用扩展控件时,右侧边距与左侧边距不匹配。向扩展器添加额外边距时,此问题更为明显。

我的目的是让每个组都作为扩展器,但两边都有边距,因此随着更多组的添加,网格列会更加“挤压”到中心。这似乎发生在左侧,而不是右侧。

我的所有列都是“自动”的,除了一个设置为 * 以便网格列始终拉伸以适应窗口。在这样做时,网格似乎很难在右侧创建适合整个列集所需的额外空间。左侧看起来不错,因为它似乎在每次创建新组时都会扩展行选择器,将网格列进一步向右推。

这是它目前的样子: http://oi58.tinypic.com/117cojb.jpg

这是我希望每次添加新组时的外观: http://oi62.tinypic.com/2rcn20w.jpg

在第二张图片中,我必须手动拖动列宽以使扩展器适合“屏幕上”。理想情况下,我希望为添加的每个新组自动处理此问题。


Window Xaml...

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="1000"
        Height="600">

    <Window.Resources>

        <!--  Data Grid  -->
        <Style TargetType="{x:Type DataGrid}">
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="RowBackground" Value="Transparent" />
            <Setter Property="AlternationCount" Value="2" />
            <Setter Property="GridLinesVisibility" Value="None" />
            <Setter Property="SelectionMode" Value="Extended" />
            <Setter Property="SelectionUnit" Value="FullRow" />
            <Setter Property="CanUserAddRows" Value="False" />
            <Setter Property="IsReadOnly" Value="True" />
            <Setter Property="AutoGenerateColumns" Value="False" />
            <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
            <Setter Property="RowHeaderWidth" Value="0" />
        </Style>

        <!--  Group Style  -->
        <Style x:Key="DefaultGroupStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander Header="{Binding Name}" 
         Margin="10"
                                  IsExpanded="True"
                                  >
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <!-- Expander -->
        <Style TargetType="{x:Type Expander}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Expander}">
                        <Grid>

                            <Border Background="LightCoral"  CornerRadius="3" Opacity="0.5" />

                            <DockPanel>

                                <StackPanel 
                                        DockPanel.Dock="Top"
                                        Orientation="Horizontal">

                                    <ToggleButton Width="20" Content=">" Margin="5" VerticalAlignment="Center" 
                                              IsChecked="{Binding Path=IsExpanded,
                                                                  RelativeSource={RelativeSource TemplatedParent}}"
                                               />

                                    <ContentPresenter  VerticalAlignment="Center" 
                                                  Content="{TemplateBinding Header}"
                                                  ContentTemplate="{TemplateBinding HeaderTemplate}"
                                                  ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
                                                  DockPanel.Dock="Top"
                                                  Focusable="false" />

                                </StackPanel>

                                <ContentPresenter x:Name="ExpanderContent"

                                              DockPanel.Dock="Bottom"
                                              Visibility="Collapsed" />
                            </DockPanel>

                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="True">
                                <Setter TargetName="ExpanderContent" Property="Visibility" Value="Visible" />
                            </Trigger>
                        </ControlTemplate.Triggers>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>

        </Style>

    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <DataGrid x:Name="IssuesGrid"
                  Margin="20"
                  ItemsSource="{Binding}">
            <DataGrid.Columns>

                <DataGridTextColumn Width="Auto"
                                    Binding="{Binding ID}"
                                    CanUserSort="False"
                                    Header="ID" />
                <DataGridTextColumn Width="Auto"
                                    Binding="{Binding Customer}"
                                    CanUserSort="False"
                                    Header="Customer" />
                <DataGridTextColumn Width="*"
                                    Binding="{Binding Title}"
                                    CanUserSort="False"
                                    Header="Title" />
                <DataGridTextColumn Width="Auto"
                                    Binding="{Binding AssignedTo}"
                                    CanUserSort="False"
                                    Header="Assigned To" />
            </DataGrid.Columns>

            <DataGrid.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource DefaultGroupStyle}">
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <DataGridRowsPresenter />
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </DataGrid.GroupStyle>

        </DataGrid>

        <StackPanel Grid.Row="1"
                    HorizontalAlignment="Center"
                    Orientation="Horizontal">
            <Button x:Name="btnGroup1"
                    Width="Auto"
                    Margin="5"
                    Content="Add  Group" />

        </StackPanel>

    </Grid>
</Window>

背后的代码...

Imports System.ComponentModel
Imports System.Collections.ObjectModel

Public Class MainWindow

    Public Items As New IssueCollection

    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

        Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer A", .Title = "A long title to take up a good amount of space"})
        Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer A", .Title = "A long title to take up a good amount of space"})
        Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})
        Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})
        Items.Add(New Issue With {.ID = "1234", .AssignedTo = "John Doe", .Customer = "Customer B", .Title = "A long title to take up a good amount of space"})

        IssuesGrid.ItemsSource = CollectionViewSource.GetDefaultView(Items)

    End Sub

    Private Sub btnGroup1_Click(sender As Object, e As RoutedEventArgs) Handles btnGroup1.Click
        CType(IssuesGrid.ItemsSource, ICollectionView).GroupDescriptions.Add(New PropertyGroupDescription("Customer"))
    End Sub

End Class

Public Class Issue
    Public Property ID As String
    Public Property AssignedTo As String
    Public Property Customer As String
    Public Property Title As String

End Class

Public Class IssueCollection
    Inherits ObservableCollection(Of Issue)
    Implements INotifyPropertyChanged

    Public Sub New()
    End Sub

End Class

关于如何解决这个问题的任何想法?- 我尝试在所有级别(即列、行演示器和扩展器)上更改边距和填充,但没有成功。

谢谢。

【问题讨论】:

标签: wpf xaml datagrid datagridviewcolumn


【解决方案1】:

我对组风格做了一点调整

    <!--  Group Style  -->
    <Style x:Key="DefaultGroupStyle" TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                    <Grid Width="{Binding ActualWidth,RelativeSource={RelativeSource TemplatedParent}}">
                        <Expander Header="{Binding Name}" Margin="10" IsExpanded="True">
                            <ItemsPresenter />
                        </Expander>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我将扩展器封装在一个网格中,并将它的宽度绑定到容器的宽度,这最终会限制孩子变得更大

但是这种方法有一个限制,即这不会重新定位网格列,因此可能会有一些伪影,我认为可以单独处理

结果

【讨论】:

  • 不幸的是限制,调整大小也会导致水平滚动条的大小增加,你做的越多。
  • 我建议实现一种自动调整列大小的行为。所以每当网格容器改变它的大小时,网格的列也会根据规则调整自己的大小。目前这只是一个想法,我没有任何具体的实现。我试试看。
  • 我还尝试修改数据网格模板以在右侧包含另一个“全选”按钮,希望如果宽度绑定到与另一个相同的宽度,它会将内容推回中间“全选”按钮,但这不起作用。
  • 有趣的是,向 PART_ScrollContentPresenter 添加 10 的边距似乎几乎可以做到
  • 很好,那么它完全解决了调整大小的问题吗?
猜你喜欢
  • 2011-08-18
  • 2015-07-03
  • 2011-08-22
  • 1970-01-01
  • 2013-07-26
  • 2010-12-01
  • 1970-01-01
  • 2015-03-20
  • 2010-11-22
相关资源
最近更新 更多