In my code I have a DataGrid
that I want to rotate for certain cases. Basically "rotating" just means switching the view mode of the DataGrid
(displaying columns horizontally or vertically).
The idea is to have a boolean variable coming from an interface. Depending on that, I want to activate/deactivate the transformed view. I think I will need like a converter or something..?
I just copy-pasted this code from another stackoverflow-question. I played a bit with it but I cannot answer questions to. I know, that following values HAVE TO be changed when rotating or not:
RotateTransform
Angle="-90"
MatrixTransform
Matrix="-1 0 0 1 0 0"
RotateTransform
Angle="-90"
ScaleTransform
ScaleX="1"
ScaleY="-1"
RotateTransform
Angle="-90"
ScaleTransform
ScaleX="1"
ScaleY="-1"
This is my XAML:
<DataGrid ItemsSource="{Binding Path=CurrentTable.DefaultView, IsAsync=True}" AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"
SelectedItem="{Binding SelectedItem}" IsReadOnly="False">
<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>
Could you help me? I really do not know, where to start and what to start with.
Edit 1:
With big help of @thatguy I was able to rotate my DataGrid
. I wonder how I can change the weird sizes of the cells after being rotated.
An example of my code.
Before rotating:
After rotating:
This is the definition of my DataGrid
:
CodePudding user response:
You do not need a converter, it can all be done in the style using triggers. Suppose you created a bool
property named IsCertainCase
in your view model which must implement the INotifyPropertyChanged
interface to notify bindings to update their value, otherwise a changed value in the view model will not be reflected in the user interface.
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.
}
Then you can create a Style
for the DataGrid
. Note that it needs to extend the default style for DataGrid
, otherwise its visual appearance or behavior might be different. That is what the BasedOn
property is for.
A DataTrigger
is used to bind the IsCertainCase
property and check whether it is True
or not.
Represents a trigger that applies property values or performs actions when the bound data meets a specified condition.
In case it is, the LayoutTransform
is applied. The other styles work just the same, with one major difference. Their DataContext
is different than the DataContext
of the DataGrid
. Consequently, a binding to IsCertainCase
would fail. In this case we use a RelativeSource
which refers to a parent element of a certain type specified with AncestorType
, here DataGrid
. As path, we specify its DataContext
and on that the property IsCertainCase
. Now we bind the same data as on the DataGrid
style.
<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>