wpf - 在 WPF 中拆分数据网格的列

标签 wpf wpfdatagrid datagridheaderborder

enter image description here我的表单中有一个数据网格,其中包含每种问题类型的列。 我希望将该列分成两列,因为我想接受后续列中每种问题类型的必答题数量和可选问题数量。

感谢 stackoverflow.com,我在 winforms 中实现了这一点。

我正在尝试在 WPF 中实现相同的目标

提前致谢

最佳答案

我想这是 DataGrid您想要的布局....对吗?

.------.-----------------.--------.
|      |   ID Details    |        |
| Name |-----------------| Status |
|      | ID   | Passport |        |
|------|------|----------|--------|
|X     | 123  | E567868  | Present|
|Y     | 236  | 7875678  | Absent |
'------'------'----------'--------'

WPF 数据网格并不支持这一点。但是您可以进行一些弹性编码。像下面这样的代码可以拆分标题。你需要小心......

When the split columns are reordered (DataGrid.ColumnReordered event), all the sibling columns under their common parent header should be moved, together. I am leaving that code to you.

DataGridHeaders 设置一些自定义样式

<Style TargetType="{x:Type Primitives:DataGridColumnHeader}" 
  x:Key="SplitHeaderStyle">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type Primitives:DataGridColumnHeader}">
        <DockPanel LastChildFill="True">
        <Grid DockPanel.Dock="Bottom">
            <Controls:DataGridHeaderBorder 
            SortDirection="{TemplateBinding SortDirection}"
            IsHovered="{TemplateBinding IsMouseOver}"
            IsPressed="{TemplateBinding IsPressed}"
            IsClickable="{TemplateBinding CanUserSort}"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Padding ="{TemplateBinding Padding}"
            SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
            SeparatorBrush="{TemplateBinding SeparatorBrush}">
            <ContentPresenter 
            Content="{Binding RelativeSource={RelativeSource TemplatedParent},
                      Path=Content[0]}"
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
            HorizontalAlignment="Center"/>
            </Controls:DataGridHeaderBorder>
            <Thumb x:Name="PART_LeftHeaderGripper"
               HorizontalAlignment="Left"
               Style="{StaticResource ColumnHeaderGripperStyle}"/>
            <Thumb x:Name="PART_RightHeaderGripper"
               HorizontalAlignment="Right"
               Style="{StaticResource ColumnHeaderGripperStyle}"/>
        </Grid>
        <Grid DockPanel.Dock="Top">
            <Controls:DataGridHeaderBorder
            HorizontalAlignment="Stretch"
            IsClickable="False"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding SeparatorBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Padding ="{TemplateBinding Padding}"
            SeparatorVisibility="{TemplateBinding Tag}"
            SeparatorBrush="{TemplateBinding SeparatorBrush}">
            <ContentPresenter 
                Content="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                          Path=Content[1]}"
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                Margin="-8,2,-10,2"/>
            </Controls:DataGridHeaderBorder>
            <Thumb x:Name="PART_LeftSplitHeaderGripper"
            HorizontalAlignment="Right"
            Visibility="{TemplateBinding Tag}"
            Style="{StaticResource ColumnHeaderGripperStyle}"/>
        </Grid>
        </DockPanel>
    </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

<Style TargetType="{x:Type Primitives:DataGridColumnHeader}" 
   BasedOn="{StaticResource SplitHeaderStyle}"
   x:Key="SplitHeaderLeftStyle">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Tag" Value="{x:Static Visibility.Visible}"/>
</Style>

<Style TargetType="{x:Type Primitives:DataGridColumnHeader}" 
   BasedOn="{StaticResource SplitHeaderStyle}"
   x:Key="SplitHeaderRightStyle">
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Tag" Value="{x:Static Visibility.Collapsed}"/>
</Style>

像这样排列列...

<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn 
         Header="Name" 
         Binding="{Binding Name}"/>
<Controls:DataGridTextColumn 
         Binding="{Binding ID}" 
    HeaderStyle="{StaticResource SplitHeaderRightStyle}">
    <Controls:DataGridTextColumn.Header>
    <x:ArrayExtension Type="System:String">
        <System:String>ID</System:String>
        <System:String>ID De</System:String>                            
    </x:ArrayExtension>
    </Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn 
         Binding="{Binding Passport}"
    HeaderStyle="{StaticResource SplitHeaderLeftStyle}">
    <Controls:DataGridTextColumn.Header>
    <x:ArrayExtension Type="System:String">
        <System:String>Passport</System:String>
        <System:String>tails</System:String>                            
    </x:ArrayExtension>
    </Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn 
            Header="Status"
            Binding="{Binding Status}"/>
  </Controls:DataGrid.Columns>

所以基本上您使用相同的默认页眉布局 DataGrid但是以一种方式破解它,使两个 header 看起来就像它们连接在一起。

C#

  1. 将您的名字命名为 DataGrid例如x:Name="MyDataGrid" .
  2. <DataGrid.Resources ..>中保留XAML中的所有样式标签。确保他们有 x:Key放。例如x:Key="SplitHeaderLeftStyle" & x:Key="SplitHeaderRightStyle"

    <DataGrid x:Name="MyDataGrid">
         <DataGrid.Resources>
             <Style 
                  TargetType="{x:Type Primitives:DataGridColumnHeader}" 
                  x:Key="SplitHeaderStyle" .../>
    
             <Style x:Key="SplitHeaderLeftStyle" 
                    BasedOn="{StaticResource SplitHeaderStyle}".../>
    
             <Style x:Key="SplitHeaderRightStyle"
                    BasedOn="{StaticResource SplitHeaderStyle}" .../>
         </DataGrid.Resources>
         ...
    </DataGrid> 
    
  3. 在您的 C# 代码中添加列时,通过 Key 设置样式.

      var dgIDColumn 
        = new DataGridTextColumn()
          {
            Header = new string[] { "ID", "ID Det" },
            Binding = new Binding() { Path = new PropertyPath("ID") },
            HeaderStyle = MyDataGrid.FindResource("SplitHeaderRightStyle") as Style;
          };
    
     MyDataGrid.Columns.Add(dgIDColumn);
    
      var dgPassportColumn 
       = new DataGridTextColumn()
         {
            Header = new string[] { "Passport", "ails" },
            Binding = new Binding() { Path = new PropertyPath("Passport") },
            HeaderStyle = MyDataGrid.FindResource("SplitHeaderLeftStyle") as Style;
         };
    
      MyDataGrid.Columns.Add(dgPassportColumn);
    

关于wpf - 在 WPF 中拆分数据网格的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12970463/

相关文章:

wpf - 访问 WPF DataGrid "empty"或 "rowcolumn" header

c# - 将 DateTime 绑定(bind)到日期和时间 EditFields

c# - 只读依赖属性更新但首次使用时不起作用

c# - 在wpf中动态添加列到DataGrid

c# - DataGrid 虚拟化绑定(bind)到带有 GroupDescriptions 的 ListCollectionView

c# - 如何创建从反射获得的类型列表

c# - 打开另一个内容对话框时出现 "Only a single ContentDialog can be open at any time."错误

wpf - 在 WPF 中使用 Multibinding 时是否必须使用转换器?

xaml 样式中的 WPF4 DataGridHeaderBorder

wpf - WPF DataGrid 的 DataGridHeaderBorder 在哪里?