wpfimagelistviewrotatetransformtransformgroup

Weird transform behavior with Images in WPF ListView


I've got a DataGrid with multiple columns. In one of the inner columns, I am displaying an image. This image needs to be rotated, so I used a TransformGroup to scale and rotate the image as needed.

If I do no rotate, using the following XAML, the image appears normally. As I change the width of the image column, the image scales as expected. It stays within the bounds of its column:

<GridViewColumn Header="Image" Width="200" x:Name="image_column">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <Image Source="{Binding Path=ImagePath}" Margin="5">
            </Image>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

Now if I attempt to rotate the image as necessary within the image column, things get weird. The column is still tied to the non-rotated image width, and the row height is tied to the non-rotated image height. The image also intrudes on its left neighbor's space. This is one variant of XAML that I have tried:

<GridViewColumn Header="Image" Width="200" x:Name="image_column">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <Image Source="{Binding Path=ImagePath}" Margin="5">
                <Image.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="0.8" ScaleY="0.8" />
                        <RotateTransform Angle="90" CenterX="0" CenterY="0" />
                        <TranslateTransform X="{Binding ElementName=image_column, Path=Width}" />
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

The TranslateTransform above is a complete hack to at least make the right edge of the image line up with the right edge of its column.

I've tried to add a Viewbox, thinking that the it would scale the way I want it to, with the rotated the image inside of it, but that didn't work.

Can anyone tell me what I am fundamentally missing here, and offer hints on how I can approach a solution? The only idea I have at this point is to rotate the image and save to disk before display.


Solution

  • You should set the LayoutTransform property instead of RenderTransform.

    <Image.LayoutTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
            <RotateTransform Angle="90"/>
        </TransformGroup>
    </Image.LayoutTransform>
    

    As the column width is fixed, the ScaleTransform seems to be redundant.

    <Image.LayoutTransform>
        <RotateTransform Angle="90"/>
    </Image.LayoutTransform>