Wpf 水平数据网格

Wpf 水平数据网格,wpf,datagrid,orientation,wpfdatagrid,Wpf,Datagrid,Orientation,Wpfdatagrid,我想要一个水平方向的WPF DataGrid,有人知道解决方案吗?我之前做过这件事,因为我们希望能够对DataGrid和PropertyGrid使用相同的控件。很多事情都需要改变,比如对齐、滚动、排序箭头的定位等。。有很多代码可以发布整个解决方案,但这应该可以让您开始。这是一个自动生成TextColumns的示例,但您可以轻松地修改它以使用其他列类型 <ScrollViewer Name="c_dataGridScrollViewer" Loaded="c_da

我想要一个水平方向的WPF DataGrid,有人知道解决方案吗?

我之前做过这件事,因为我们希望能够对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>

我之前做过这件事,因为我们希望能够对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是要拦截的: