我的表单中有一个datagrid,其中包含每个问题类型的列。 我希望将该列拆分为两列,因为我希望接受后续列中每个问题类型的强制数和可选问题数。
我已经在winforms中实现了这一点,感谢stackoverflow.com。
我试图在WPF中实现相同的目标
提前致谢
答案 0 :(得分: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>
所以基本上你使用DataGrid
的相同默认标题布局,但是以两个标题看起来的方式进行黑客攻击,就像它们连接在一起一样。
<强> C#强>
DataGrid
命名,例如x:Name="MyDataGrid"
。将XAML中的所有样式保留在<DataGrid.Resources ..>
标记中。确保他们设置了x:Key
。例如x:Key="SplitHeaderLeftStyle"
&amp; 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>
,按照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);
答案 1 :(得分: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>
答案 2 :(得分: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>
我已将AutoColumns属性添加到GridHelper类中,详见this link
#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