【问题标题】:WPF horizontal DataGridWPF 水平数据网格
【发布时间】:2011-05-07 04:17:16
【问题描述】:

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

【问题讨论】:

    标签: wpf datagrid orientation wpfdatagrid


    【解决方案1】:

    哇,很好的解决方案,谢谢!它还需要修改上/下和左/右按钮之间的行/列选择开关。我试图在 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;
            }
        }
    }
    

    【讨论】:

    【解决方案2】:

    我之前已经这样做了,因为我们希望能够对DataGridPropertyGrid 使用相同的控件。很多事情都需要改变(比如对齐、滚动、排序箭头的定位等)。有很多代码可以发布整个解决方案,但这应该可以帮助您入门。这是一个使用自动生成的 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>
    

    当生成 Columns 时,我们反转它们的位置并旋转 TextBlocks 和 TextBoxes(这在对齐、模糊等方面比旋转 DataGridCell 更好)

    private void c_dataGridScrollViewer_Loaded(object sender, RoutedEventArgs e)
    {
        // Add MouseWheel support for the datagrid scrollviewer.
        c_dataGrid.AddHandler(MouseWheelEvent, new RoutedEventHandler(DataGridMouseWheelHorizontal), true);
    }
    
    private void DataGridMouseWheelHorizontal(object sender, RoutedEventArgs e)
    {
        MouseWheelEventArgs eargs = (MouseWheelEventArgs)e;
        double x = (double)eargs.Delta;
        double y = c_dataGridScrollViewer.VerticalOffset;
        c_dataGridScrollViewer.ScrollToVerticalOffset(y - x);
    }
    
    private void c_dataGrid_AutoGeneratedColumns(object sender, EventArgs e)
    {
        TransformGroup transformGroup = new TransformGroup();
        transformGroup.Children.Add(new RotateTransform(90));
        foreach (DataGridColumn dataGridColumn in c_dataGrid.Columns)
        {
            if (dataGridColumn is DataGridTextColumn)
            {
                DataGridTextColumn dataGridTextColumn = dataGridColumn as DataGridTextColumn;
    
                Style style = new Style(dataGridTextColumn.ElementStyle.TargetType, dataGridTextColumn.ElementStyle.BasedOn);
                style.Setters.Add(new Setter(TextBlock.MarginProperty, new Thickness(0, 2, 0, 2)));
                style.Setters.Add(new Setter(TextBlock.LayoutTransformProperty, transformGroup));
                style.Setters.Add(new Setter(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Center));
    
                Style editingStyle = new Style(dataGridTextColumn.EditingElementStyle.TargetType, dataGridTextColumn.EditingElementStyle.BasedOn);
                editingStyle.Setters.Add(new Setter(TextBox.MarginProperty, new Thickness(0, 2, 0, 2)));
                editingStyle.Setters.Add(new Setter(TextBox.LayoutTransformProperty, transformGroup));
                editingStyle.Setters.Add(new Setter(TextBox.HorizontalAlignmentProperty, HorizontalAlignment.Center));
    
                dataGridTextColumn.ElementStyle = style;
                dataGridTextColumn.EditingElementStyle = editingStyle;
            }
        }
        List<DataGridColumn> dataGridColumns = new List<DataGridColumn>();
        foreach (DataGridColumn dataGridColumn in c_dataGrid.Columns)
        {
            dataGridColumns.Add(dataGridColumn);
        }
        c_dataGrid.Columns.Clear();
        dataGridColumns.Reverse();
        foreach (DataGridColumn dataGridColumn in dataGridColumns)
        {
            c_dataGrid.Columns.Add(dataGridColumn);
        }
    }
    

    【讨论】:

    • 谢谢!它工作得很好,启用时的水平滚动条出现在顶部(这是意料之中的),并且标题调整大小的行为很奇怪(也是意料之中的),但这对我来说是一个很好的起点。你有机会发布你的整个解决方案吗?将不胜感激;)
    • 对不起,我不能。它内置在我以前的公司拥有的解决方案中。如果您发布问题,我可以为您提供具体帮助,但我无法上传整个解决方案。祝你好运!
    • 再想一想,获得控件下方的水平滚动条的一些帮助会很棒
    • 更新了我的例子。父 ScrollViewer 处理滚动
    • 在下面查看我的回答,了解重要的改进。
    【解决方案3】:

    我真的站在巨人的肩膀上 :-) 但是,我还有一个额外的增强功能。

    @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>
    

    【讨论】:

      【解决方案4】:

      我已经简化了一些以前的解决方案。我不喜欢带有额外滚动查看器的黑魔法,所以我不使用它。但相反,我使用了额外的比例变换。

      <DataGrid.LayoutTransform>
          <TransformGroup>
              <RotateTransform Angle="-90"/>
              <ScaleTransform ScaleX="1" ScaleY="-1" />
          </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>
      

      如果是预定义的列列表,可以直接在 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>
      

      这可以让您完全摆脱代码隐藏。

      【讨论】:

        【解决方案5】:

        我发现这种方法非常有用,但是我做了一个旋转和镜像:

        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>
        

        通过使用镜像,我将列列表末尾的字段放在底部而不是顶部。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-05
          • 1970-01-01
          • 2011-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多