酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

WindowsストアアプリでTextBlockを90度回転して表示させたい #win8dev_jp

(ブログ書いてから気付いたのですが、90度回転ではなくて270度回転ですね……)

やりたいこと

可変長のテキストを下図のように270度回転させたいです。

f:id:ch3cooh393:20130719001202j:plain

関係ない話ですが、最近ものすごく口下手で、UI上の問題を口頭でうまく説明できないことが多くて、こんな感じのイラストを毎日たくさん書いています。

ベースとなるXAML

<Page
    x:Class="App2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Grid Background="Red" HorizontalAlignment="Center" 
            VerticalAlignment="Bottom" Margin="0,0,0,20" >
            <TextBlock Text="ここには可変長のテキストが入る" 
                Foreground="Black" TextAlignment="Center" FontSize="24" />
        </Grid>

    </Grid>
</Page>

上記のXAMLを表示させると下図のようになります。

f:id:ch3cooh393:20130719001539p:plain

この「ここには可変長のテキストが入る」というTextBlockを最初のやりたいことのイラストのように270度回転させたいと考えています。

1. 270度回転させてみました(失敗)

RenderTransformOrigin="0.5,0.5"を設定して、CompositeTransform.Rotatation="270"を設定してみました。

        <Grid Background="Red" HorizontalAlignment="Right" 
              VerticalAlignment="Center" Margin="0,0,20,0"
              RenderTransformOrigin="0.5,0.5" >
            <TextBlock Foreground="Black" TextAlignment="Center" 
                       FontSize="24" 
                       Text="ここには可変長のテキストが入る" />
            <Grid.RenderTransform>
                <CompositeTransform Rotation="270" />
            </Grid.RenderTransform>
        </Grid>

上記のXAMLを表示させると下図のようになります。

f:id:ch3cooh393:20130719002158p:plain

液晶の端からのマージンが違いすぎる結果になりました。さらにテキストの文字数を変更するとマージンが変わる……

f:id:ch3cooh393:20130719002349p:plain

2. RenderTransformOrigin="0,0"を指定する(失敗)

RenderTransformOrigin="0,0"を指定してみては?と教えて頂きましたので試してみました。

        <Grid Background="Red" HorizontalAlignment="Right" 
              VerticalAlignment="Center" Margin="0,0,20,0"
              RenderTransformOrigin="0.5,0.5" >
            <TextBlock Foreground="Black" TextAlignment="Center" 
                       FontSize="24" 
                       Text="ここには可変長のテキストが入る" />
            <Grid.RenderTransform>
                <CompositeTransform Rotation="270" />
            </Grid.RenderTransform>
        </Grid>

上記のXAMLを表示させると下図のようになります。

f:id:ch3cooh393:20130719002556p:plain

RenderTransformOrigin="0.5,0.5"を設定したものよりもズレてしまいました。

3. LayoutTransform使えば簡単に出来るよ (WinRTでは非対応)

ぐらばく(@Grabacr07)さんに教えて頂いたのですが、WPFだとLayoutTransformというのがあって、このやりたいことを比較的簡単に実装できるようです。

これはすごい!とWinRTで試したところ、WinRTにはLayoutTransformがないのが分かり使えないことが発覚……

ただ、

WPFで同じことをする機会があれば、LayoutTransformを使うと覚えておきます!

(追記)

WindowsストアアプリにLayoutTransformがないなら作ってしまえという高橋さんの提案。

4. Gridを正方形にして270度回転させる (おしい)

いけちょ(@ikeda_shogouki)さんに教えて頂きました。技術的には高橋忍さんのMediaCaptureを回転させる方法と同じ感じでしょうか。

XAMLは以下の通りです。

        <Grid Background="Blue"
              HorizontalAlignment="Right"
              VerticalAlignment="Center"
              Margin="0,0,20,0"
              RenderTransformOrigin="0.5,0.5"
              Width="{Binding ActualWidth, ElementName=innnerTextBlock, Mode=OneWay}"
              Height="{Binding ActualWidth, ElementName=innnerTextBlock, Mode=OneWay}">
            <TextBlock Name="innnerTextBlock"
                       Foreground="Black"
                       TextAlignment="Center"
                       VerticalAlignment="Bottom"
                       FontSize="24"
                       Text="ここには可変長のテキストが入る" />
            <Grid.RenderTransform>
                <CompositeTransform Rotation="270" />
            </Grid.RenderTransform>
        </Grid>

上記のXAMLを表示させると下図のようになります。

f:id:ch3cooh393:20130719015105p:plain

液晶右からのマージンに関しては20pxになりました!ただ、頂いたXAMLの適用の仕方がおかしかったかもしれません……

5. Gridを正方形にして270度回転させる その2

4.のいけちょ(@ikeda_shogouki)さんのXAMLが良い感じでしたので、Gridをもう一枚被せてブルーの背景色が反映される領域を固定してみました。

<Page
    x:Class="App2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid x:Name="rootGrid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <Grid HorizontalAlignment="Right"
              VerticalAlignment="Center"
              Margin="0,0,20,0"
              RenderTransformOrigin="0.5,0.5"
              Width="{Binding ActualWidth, ElementName=innnerTextBlock, Mode=OneWay}"
              Height="{Binding ActualWidth, ElementName=innnerTextBlock, Mode=OneWay}">

            <Grid Background="Blue" 
                HorizontalAlignment="Center" VerticalAlignment="Bottom">
                <TextBlock Name="innnerTextBlock"
                           Foreground="Black"
                           TextAlignment="Center"
                           VerticalAlignment="Bottom"
                           FontSize="24"
                           Text="ここには可変長のテキストが入る" />
            </Grid>
            
            <Grid.RenderTransform>
                <CompositeTransform Rotation="270" />
            </Grid.RenderTransform>
        </Grid>
    </Grid>
</Page>

上記のXAMLを表示させると下図のようになります。

f:id:ch3cooh393:20130719030449p:plain

可変長のテキストという要件を満たせているか確認するために、テキストを短くしてみます。

f:id:ch3cooh393:20130719030459p:plain

1.ではテキストを短くすると、右側のマージンがそれに応じて変わってしまいましたが、こちらでは大丈夫そうです。