XAML 布尔绑定,决定是否旋转DataGrid

eit6fx6z  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(149)

在我的代码中,我有一个DataGrid,我想在某些情况下旋转它。基本上,“旋转”只是意味着切换DataGrid的视图模式(水平或垂直显示列)。
这个想法是有一个布尔变量来自一个接口。根据这一点,我想激活/停用转换的视图。我想我会需要像一个转换器或东西..?
我只是从另一个stackoverflow问题复制粘贴此代码。我玩了一点,但我不能回答问题。我知道,以下值必须改变时旋转或不:

  • RotateTransformAngle="-90"
  • MatrixTransformMatrix="-1 0 0 1 0 0"
  • RotateTransformAngle="-90"
  • ScaleTransformScaleX="1"ScaleY="-1"
  • RotateTransformAngle="-90"
  • x一个月13个月1个月x一个月14个月1个月x一个月15个月1个月

这是我的XAML:

<DataGrid ItemsSource="{Binding Path=CurrentTable.DefaultView,IsAsync=True}"
          AutoGenerateColumns="True" 
          AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" SelectedItem="{Binding 
          SelectedItem}" IsReadOnly="False" 
          PreviewMouseRightButtonDown="DataGrid_PreviewMouseRightButtonDown" 
          PreviewMouseLeftButtonDown="DataGrid_PreviewMouseLeftButtonDown"  
          CellEditEnding="DataGrid_CellEditEnding" CanUserAddRows="False" 
          CanUserReorderColumns="False" 
          EnableColumnVirtualization="True" EnableRowVirtualization="True" 
          VirtualizingStackPanel.VirtualizationMode="Standard">

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

你能帮我吗?我真的不知道,从哪里开始,从什么开始。
编辑1:在@thatguy的帮助下,我可以旋转我的DataGrid。我想知道如何在旋转后改变单元格的奇怪大小。我的代码示例。
旋转前:

旋转后:

y4ekin9u

y4ekin9u1#

假设您在视图模型中创建了一个名为IsCertainCasebool属性,它必须实现INotifyPropertyChanged接口来通知绑定更新它们的值,否则视图模型中更改的值将不会反映在用户界面中。

public class MyViewModel : INotifyPropertyChanged
{
      private bool _isCertainCase;
   public bool IsCertainCase
   {
      get => _isCertainCase;
      set
      {
         if (_isCertainCase == value)
            return;
   
         _isCertainCase = value;
         OnPropertyChanged();
      }
   }

   public event PropertyChangedEventHandler PropertyChanged;
   
   protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }

   // ...other code.
}

然后,您可以为DataGrid创建一个Style。注意,它需要 * 扩展 * DataGrid的默认样式,否则它的视觉外观或行为可能会不同。这就是BasedOn属性的作用。
DataTrigger用于绑定IsCertainCase属性,并检查它是否为True
表示在绑定数据满足指定条件时应用属性值或执行操作的触发器。
在这种情况下,应用LayoutTransform。其他样式的工作方式是一样的,但有一个主要的区别。它们的DataContext不同于DataGridDataContext。因此,绑定到IsCertainCase将失败。在本例中,我们使用RelativeSource,它引用由AncestorType指定的某种类型的父元素。这里是DataGrid。作为path,我们指定它的DataContext,并在其上指定属性IsCertainCase。现在我们绑定与DataGrid样式相同的数据。

<DataGrid ItemsSource="{Binding Path=CurrentTable.DefaultView, IsAsync=True}" AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"   
          SelectedItem="{Binding SelectedItem}" IsReadOnly="False">
   <DataGrid.Style>
      <Style TargetType="{x:Type DataGrid}"
             BasedOn="{StaticResource {x:Type DataGrid}}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding IsCertainCase}" Value="True">
               <Setter Property="LayoutTransform">
                  <Setter.Value>
                     <TransformGroup>
                        <RotateTransform Angle="90"/>
                        <MatrixTransform Matrix="-1 0 0 1 0 0" />
                     </TransformGroup>
                  </Setter.Value>
               </Setter>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.Style>
   <DataGrid.ColumnHeaderStyle>
      <Style TargetType="{x:Type DataGridColumnHeader}"
             BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding DataContext.IsCertainCase, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="True">
               <Setter Property="LayoutTransform">
                  <Setter.Value>
                     <TransformGroup>
                        <RotateTransform Angle="-90"/>
                        <ScaleTransform ScaleX="1" ScaleY="-1" />
                     </TransformGroup>
                  </Setter.Value>
               </Setter>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.ColumnHeaderStyle>
   <DataGrid.CellStyle>
      <Style TargetType="DataGridCell"
             BasedOn="{StaticResource {x:Type DataGridCell}}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding DataContext.IsCertainCase, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="True">
               <Setter Property="LayoutTransform">
                  <Setter.Value>
                     <TransformGroup>
                        <RotateTransform Angle="-90"/>
                        <ScaleTransform ScaleX="1" ScaleY="-1" />
                     </TransformGroup>
                  </Setter.Value>
               </Setter>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.CellStyle>
</DataGrid>

更新编辑

DataGrid与应用的这些转换并不完全兼容。实际上,您可以这样做,并且列和单元格的方向将正确,但调整大小仍然假设所有内容的方向都与以前一样,这意味着您交换了宽度和高度,并且列调整大小指示器仍将水平显示,并以这种方式工作。虽然在视觉上所有的东西都是垂直缩放的。请注意,可能会有其他的副作用,无意中使用的DataGrid
出现奇数单元格缩放的原因很简单,因为标题的大小已根据其内容调整,并且在布局转换时不会重新计算大小。现在宽度和高度已交换,行高等于以前的列宽。以下附加属性提供了一种解决方法,即通过重置所有列的Width来强制重新计算大小。

public static class DataGridLayoutTransformProperties
{
   public static bool GetIsHeaderSizeUpdateRequired(DependencyObject obj)
   {
      return (bool)obj.GetValue(IsHeaderSizeUpdateRequiredProperty);
   }

   public static void SetIsHeaderSizeUpdateRequired(DependencyObject obj, bool value)
   {
      obj.SetValue(IsHeaderSizeUpdateRequiredProperty, value);
   }

   public static readonly DependencyProperty IsHeaderSizeUpdateRequiredProperty = DependencyProperty.RegisterAttached(
      "IsHeaderSizeUpdateRequired", typeof(bool), typeof(DataGridLayoutTransformProperties),
      new PropertyMetadata(false, IsHeaderSizeUpdateRequired));

   private static void IsHeaderSizeUpdateRequired(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
      var dataGrid = (DataGrid)d;
      var isHeaderSizeUpdateRequired = (bool)e.NewValue;
      if (isHeaderSizeUpdateRequired)
      {
         foreach (var dataGridColumn in dataGrid.Columns)
         {
            dataGridColumn.Width = 0;
            dataGridColumn.Width = DataGridLength.Auto;
         }
      }
   }
}

DataGrid上的附加属性IsHeaderSizeUpdateRequired绑定到IsCertainCase

<DataGrid ... local:DataGridLayoutTransformProperties.IsHeaderSizeUpdateRequired="{Binding IsCertainCase}">

相关问题