2010-11-09 69 views

回答

18

我之前做過這個,因爲我們希望能夠對DataGridPropertyGrid使用相同的控件。許多東西都必須改變(比如對齊,滾動,排序箭頭的位置等)。有很多代碼可以發佈整個解決方案,但這應該讓你開始。這是自動生成的TextColumns的一個例子,但您可以輕鬆修改它以使用其他列類型。

alt text

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

並生成列時,我們扭轉他們的位置和旋轉的TextBlocks和文本框(這比在對準方面旋轉所述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); 
    } 
} 
+0

謝謝!它工作得很好,水平滾動條啓用時會出現在頂部(這是預期的),頭部大小調整行爲很奇怪(也是可以預料的),但這對我來說是一個很好的起點。你有沒有機會發布你的整個解決方案?將非常感激;) – eriksmith200 2010-11-09 12:29:37

+0

對不起,我不能。它是由我以前的公司自己的解決方案構建的。如果您發佈問題,我可以幫助您解決具體問題,但無法上傳整個解決方案。祝你好運! – 2010-11-09 13:15:25

+0

好的,謝謝,現在它足夠了,因爲我原型化了一些用戶界面:) – eriksmith200 2010-11-09 13:39:55

7

我簡化了一點以前的解決方案。我不喜歡額外的scrollviewer黑魔法,所以我不使用它。但是,我使用額外的比例轉換。

<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 transfom內容的單元格:

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

這可以讓你完全代碼隱藏逃生。

2

我發現這種方法非常有用,我不過做了旋轉和鏡像:

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> 

通過使用鏡像我有場在年底列底部的列表而不是頂部。

16

我確實站在巨人的肩膀上:-)但是,我有一個額外的增強。

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