3

ここに画像の説明を入力質問の種類ごとに列を持つフォームにデータグリッドがあります。後続の列の質問タイプごとに、必須の質問の数とオプションの質問の数を受け入れたいので、その列を2つに分割したいと思います。

stackoverflow.com のおかげで、winforms でこれを達成しました。

私はWPFで同じことを達成しようとしています

前もって感謝します

4

3 に答える 3

1

これはDataGridあなたが望むレイアウトだと思います....そうですか?

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

WPF データグリッドはこれを容易にサポートしません。ただし、伸縮性のあるコーディングを行うことはできます。以下のようなコードは、ヘッダーを分割できます。あなたは注意する必要があります...

分割された列が並べ替えられた場合 (DataGrid.ColumnReordered イベント)、共通の親ヘッダーの下にあるすべての兄弟列を一緒に移動する必要があります。そのコードはあなたに任せます。

いくつかのカスタムスタイルがあります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>

したがって、基本的には同じデフォルトのヘッダー レイアウトを使用しますが、2 つのヘッダーが結合されているように見えるDataGridようにハックします。

C#

  1. DataGridあなたの例に名前を付けますx:Name="MyDataGrid"
  2. XAML のすべてのスタイルを<DataGrid.Resources ..>タグに保持します。設定されていることを確認してください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);
    
于 2012-10-23T11:40:57.187 に答える
0
<DataGrid ItemsSource="{Binding PeopleList}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Name">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="{x:Type local:Person}">
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn>
            <DataGridTemplateColumn.HeaderTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="10"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <TextBlock Text="Question1" Grid.ColumnSpan="2"/>
                        <TextBlock Text="Compulsory" Grid.Row="1"/>
                        <TextBlock Text="Optional Q" Grid.Row="1" Grid.Column="2"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.HeaderTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="{x:Type local:Person}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="65"/>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Question.Col1}"/>
                        <TextBlock Text="{Binding Question.Col2}" Grid.Column="2"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
于 2012-10-19T12:37:04.863 に答える
0

ItemsControl.ItemContainerStyle の DataTriggers の Row/Column/ColumnSpan/RowSpan を好みに合わせて変更できます。

<ItemsControl ItemsSource="{Binding Path=Cells}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid 
                local:GridHelpers.ColumnCount="{Binding NumOfColumns}"
                local:GridHelpers.AutoColumns="0,1"
                local:GridHelpers.RowCount="{Binding NumOfRows}"
                local:GridHelpers.AutoRows="0,1">
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Row" Value="{Binding Path=RowIndex}"/>
            <Setter Property="Grid.Column" Value="{Binding Path=ColumnIndex}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=CellType}" Value="BaseCell">
                    <Setter Property="ContentTemplate" Value="{StaticResource BaseCell}"/>
                    <Setter Property="Grid.ColumnSpan" Value="{Binding Path=ColumnSpan}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=CellType}" Value="CornerHeader">
                    <Setter Property="ContentTemplate" Value="{StaticResource CornerHeader}"/>
                    <Setter Property="Grid.RowSpan" Value="2"/>
                    <Setter Property="Grid.ColumnSpan" Value="2"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=CellType}" Value="PersonNameCell">
                    <Setter Property="ContentTemplate" Value="{StaticResource PersonNameCell}"/>
                </DataTrigger>
                ...
            </Style.Triggers>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

このリンクで説明されている GridHelper クラスに AutoColumns プロパティを追加しました

    #region AutoColumns Property

    /// <summary>
    /// Makes the specified Column's Width equal to Auto. 
    /// Can set on multiple Columns
    /// </summary>
    public static readonly DependencyProperty AutoColumnsProperty =
        DependencyProperty.RegisterAttached(
            "AutoColumns", typeof(string), typeof(GridHelpers),
            new PropertyMetadata(string.Empty, AutoColumnsChanged));

    // Get
    public static string GetAutoColumns(DependencyObject obj)
    {
        return (string)obj.GetValue(AutoColumnsProperty);
    }

    // Set
    public static void SetAutoColumns(DependencyObject obj, string value)
    {
        obj.SetValue(AutoColumnsProperty, value);
    }

    // Change Event - Makes specified Column's Width equal to Auto
    public static void AutoColumnsChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
            return;

        SetAutoColumns((Grid)obj);
    }

    private static void SetAutoColumns(Grid grid)
    {
        string[] autoColumns = GetAutoColumns(grid).Split(',');

        for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
        {
            if (autoColumns.Contains(i.ToString()))
                grid.ColumnDefinitions[i].Width = GridLength.Auto;
        }
    }

    private static void SetAutoRows(Grid grid)
    {
        string[] autoRows = GetAutoRows(grid).Split(',');

        for (int i = 0; i < grid.RowDefinitions.Count; i++)
        {
            if (autoRows.Contains(i.ToString()))
                grid.RowDefinitions[i].Height = GridLength.Auto;
        }
    }
    #endregion
于 2012-10-22T19:46:16.007 に答える