Wpf 水平数据网格
我想要一个水平方向的WPF DataGrid,有人知道解决方案吗?我之前做过这件事,因为我们希望能够对DataGrid和PropertyGrid使用相同的控件。很多事情都需要改变,比如对齐、滚动、排序箭头的定位等。。有很多代码可以发布整个解决方案,但这应该可以让您开始。这是一个自动生成TextColumns的示例,但您可以轻松地修改它以使用其他列类型Wpf 水平数据网格,wpf,datagrid,orientation,wpfdatagrid,Wpf,Datagrid,Orientation,Wpfdatagrid,我想要一个水平方向的WPF DataGrid,有人知道解决方案吗?我之前做过这件事,因为我们希望能够对DataGrid和PropertyGrid使用相同的控件。很多事情都需要改变,比如对齐、滚动、排序箭头的定位等。。有很多代码可以发布整个解决方案,但这应该可以让您开始。这是一个自动生成TextColumns的示例,但您可以轻松地修改它以使用其他列类型 <ScrollViewer Name="c_dataGridScrollViewer" Loaded="c_da
<ScrollViewer Name="c_dataGridScrollViewer"
Loaded="c_dataGridScrollViewer_Loaded"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="c_dataGrid"
HorizontalAlignment="Left"
VerticalAlignment="Top"
AutoGeneratedColumns="c_dataGrid_AutoGeneratedColumns"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="90"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="-90"/>
</TransformGroup>
</DataGrid.LayoutTransform>
</DataGrid>
</ScrollViewer>
我之前做过这件事,因为我们希望能够对DataGrid和PropertyGrid使用相同的控件。很多事情都需要改变,比如对齐、滚动、排序箭头的定位等。。有很多代码可以发布整个解决方案,但这应该可以让您开始。这是一个自动生成TextColumns的示例,但您可以轻松地修改它以使用其他列类型
<ScrollViewer Name="c_dataGridScrollViewer"
Loaded="c_dataGridScrollViewer_Loaded"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="c_dataGrid"
HorizontalAlignment="Left"
VerticalAlignment="Top"
AutoGeneratedColumns="c_dataGrid_AutoGeneratedColumns"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="90"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="-90"/>
</TransformGroup>
</DataGrid.LayoutTransform>
</DataGrid>
</ScrollViewer>
我简化了一点以前的解决方案。我不喜欢附加scrollviewer的黑魔法,所以我不使用它。但是我使用了额外的比例变换 在预定义列列表的情况下,可以直接在XAML中转换单元格内容:
<Style x:Key="TextCellStyle" TargetType="{x:Type TextBlock}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
这允许您完全摆脱代码隐藏。我简化了前面的一点解决方案。我不喜欢附加scrollviewer的黑魔法,所以我不使用它。但是我使用了额外的比例变换 在预定义列列表的情况下,可以直接在XAML中转换单元格内容:
<Style x:Key="TextCellStyle" TargetType="{x:Type TextBlock}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
这使您能够完全摆脱代码隐藏。我发现这种方法非常有用,但我进行了旋转和镜像:
TransformGroup transformGroup = new TransformGroup();
transformGroup.Children.Add(new RotateTransform(90));
transformGroup.Children.Add(new MatrixTransform(-1, 0, 0, 1, 0, 0));
或在Xaml中:
<!-- we rotate the whole DataGrid by -90 degree and then mirror via y-Axis so that it is docked vertically to the left side-->
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<MatrixTransform Matrix="-1,0,0,1,0,0"/>
</TransformGroup>
</DataGrid.LayoutTransform>
通过使用镜像,我将列列表末尾的字段放在底部而不是顶部。我发现这种方法非常有用,但我进行了旋转和镜像:
TransformGroup transformGroup = new TransformGroup();
transformGroup.Children.Add(new RotateTransform(90));
transformGroup.Children.Add(new MatrixTransform(-1, 0, 0, 1, 0, 0));
或在Xaml中:
<!-- we rotate the whole DataGrid by -90 degree and then mirror via y-Axis so that it is docked vertically to the left side-->
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<MatrixTransform Matrix="-1,0,0,1,0,0"/>
</TransformGroup>
</DataGrid.LayoutTransform>
通过使用镜像,我将字段放在列列表末尾的底部,而不是顶部。我确实站在巨人的肩膀上:-但是,我还有一个额外的增强功能 @dimaKudr提出了一种无需代码隐藏即可转换预定义列的方法,@FrankE改进了列的顺序。我添加的是一种使用DataGrid.CellStyle模板转换自动生成的列AutoGenerateColumns=True的方法。因此,完整而优雅的解决方案是:
<DataGrid ItemsSource="{Binding YourObservableCollection}"
AutoGenerateColumns="True"
AutoGeneratingColumn="OnAutoGeneratingColumn">
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<MatrixTransform Matrix="-1,0,0,1,0,0"/>
</TransformGroup>
</DataGrid.LayoutTransform>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}"
BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
</DataGrid>
我真的站在巨人的肩膀上:-但是,我还有一个额外的提升 @dimaKudr提出了一种无需代码隐藏即可转换预定义列的方法,@FrankE改进了列的顺序。我添加的是一种使用DataGrid.CellStyle模板转换自动生成的列AutoGenerateColumns=True的方法。因此,完整而优雅的解决方案是:
<DataGrid ItemsSource="{Binding YourObservableCollection}"
AutoGenerateColumns="True"
AutoGeneratingColumn="OnAutoGeneratingColumn">
<DataGrid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<MatrixTransform Matrix="-1,0,0,1,0,0"/>
</TransformGroup>
</DataGrid.LayoutTransform>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}"
BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="-90"/>
<ScaleTransform ScaleX="1" ScaleY="-1" />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
</DataGrid>
哇,很好的解决方案,谢谢!它还需要修改上/下和左/右按钮之间的行/列选择开关。我试图在DataGrid的keydown或keyup事件中涵盖这一点,但这种行为有点奇怪,前后翻转选择。有谁有比下面更好的解决方案吗?这只是通过wat向左移动和向右移动的代码最初是行
private void c_dataGrid_KeyUp(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Tab:
if (Keyboard.IsKeyDown(Key.LeftShift))
{
if (c_dataGrid.SelectedIndex > 0)
{
c_dataGrid.SelectedIndex--;
}
}
else
{
if (c_dataGrid.SelectedIndex < c_dataGrid.Items.Count - 1)
{
c_dataGrid.SelectedIndex++;
}
}
e.Handled = true;
break;
}
}
}
哇,很好的解决方案,谢谢!它还需要修改上/下和左/右按钮之间的行/列选择开关。我试图在DataGrid的keydown或keyup事件中涵盖这一点,但这种行为有点奇怪,前后翻转选择。有谁有比下面更好的解决方案吗?这只是通过wat向左移动和向右移动的代码最初是行
private void c_dataGrid_KeyUp(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Tab:
if (Keyboard.IsKeyDown(Key.LeftShift))
{
if (c_dataGrid.SelectedIndex > 0)
{
c_dataGrid.SelectedIndex--;
}
}
else
{
if (c_dataGrid.SelectedIndex < c_dataGrid.Items.Count - 1)
{
c_dataGrid.SelectedIndex++;
}
}
e.Handled = true;
break;
}
}
}
谢谢它工作得很好,启用时水平滚动条出现在顶部,这是意料之中的,标题大小调整行为也很奇怪,但这对我来说是一个很好的起点。您是否有可能发布整个解决方案?非常感谢;对不起,我不能。它内置于我以前的公司拥有的解决方案中。如果你提出问题,我可以在细节上帮助你,但我无法上传整个解决方案。祝你好运再想一想,在我的示例中,获得控件下方水平滚动条的一些帮助将非常有用。父ScrollViewer处理滚动查看下面的我的答案以获得重要的增强。谢谢!它工作得很好,启用时水平滚动条出现在顶部,这是意料之中的,标题大小调整行为也很奇怪,但这对我来说是一个很好的起点。您是否有可能发布整个解决方案?那会是一场灾难
我非常感激你;对不起,我不能。它内置于我以前的公司拥有的解决方案中。如果你提出问题,我可以在细节上帮助你,但我无法上传整个解决方案。祝你好运再想一想,在我的示例中,获得控件下方水平滚动条的一些帮助将非常有用。父ScrollViewer处理滚动查看下面我的答案以获得重要的增强。显然,PreviewKeyDown是要拦截的:显然,PreviewKeyDown是要拦截的: