2010-11-09 41 views

Trả lời

18

Tôi đã thực hiện việc này sớm hơn vì chúng tôi muốn có thể sử dụng cùng một điều khiển cho một số DataGridPropertyGrid. Rất nhiều thứ phải được thay đổi (như căn chỉnh, cuộn, định vị các mũi tên sắp xếp vv). Có rất nhiều cách để đăng toàn bộ giải pháp nhưng điều này sẽ giúp bạn bắt đầu. Đây là một ví dụ với các TextColumns được tạo tự động nhưng bạn có thể dễ dàng sửa đổi nó để sử dụng các kiểu cột khác.

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> 

Và khi cột được tạo ra, chúng ta đảo ngược vị trí của họ và xoay TextBlocks và textbox (Đây là tốt hơn so với quay DataGridCell về sự liên kết, làm mờ, vv)

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

Cảm ơn! Nó hoạt động khá tốt, thanh cuộn ngang khi được bật xuất hiện ở trên cùng (được mong đợi) và hành vi thay đổi kích thước tiêu đề là lạ (cũng được mong đợi) nhưng đây là điểm khởi đầu tốt cho tôi. Bất kỳ cơ hội nào của bạn gửi toàn bộ giải pháp của bạn? Sẽ được rất nhiều đánh giá cao;) – eriksmith200

+0

Xin lỗi, tôi không thể. Nó được xây dựng thành giải pháp của công ty trước đây của tôi. Tôi có thể giúp bạn về các chi tiết cụ thể nếu bạn đăng câu hỏi nhưng tôi không thể tải lên toàn bộ giải pháp. Chúc may mắn! –

+0

Ok cảm ơn, bây giờ nó đủ như tôi đang tạo mẫu một số giao diện người dùng :) – eriksmith200

7

Tôi đã đơn giản hóa một chút giải pháp trước đó. Tôi không thích ma thuật đen với scrollviewer bổ sung, vì vậy tôi không sử dụng nó. Nhưng thay vào đó tôi sử dụng chuyển đổi quy mô bổ sung.

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

Trong trường hợp danh sách được xác định trước của colums nó có thể transfom tế bào nội dung trực tiếp trong 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> 

này cho phép bạn hoàn toàn thoát khỏi codebehind.

2

tôi thấy phương pháp này rất hữu ích, tôi tuy nhiên đã làm một vòng xoay và một mirroring:

TransformGroup transformGroup = new TransformGroup(); 
transformGroup.Children.Add(new RotateTransform(90)); 
transformGroup.Children.Add(new MatrixTransform(-1, 0, 0, 1, 0, 0)); 

hoặc trong 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> 

Bằng việc sử dụng mirroring Tôi có lĩnh vực này ở phần cuối của danh sách cột ở dưới cùng thay vì ở trên cùng.

16

Tôi thực sự đang đứng trên vai của những người khổng lồ ở đây :-) nhưng, tôi có thêm tính năng nâng cao.

@dimaKudr đề xuất một cách để chuyển đổi các cột được xác định trước mà không có mã phía sau và @FrankE đã tinh chỉnh thứ tự các cột. Những gì tôi đang thêm là một cách để biến đổi, cột được tạo tự động (AutoGenerateColumns="True"), bằng cách sử dụng mẫu DataGrid.CellStyle. Vì vậy, giải pháp hoàn chỉnh (và khá thanh lịch) là:

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