Search code examples
windows-phone-7textblockprojection

Why does TextBlock not show up with Projection attribute in a canvas?


I got this piece of code:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Canvas>
        <TextBlock Name="txtblk"
                   Canvas.Left="100" Canvas.Top="100"
                   Text="ROTATE">
        </TextBlock>
    </Canvas>
</Grid>

It works well and I can see my TextBlock. But if I add a 'Projection' attribute to it:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Canvas>
        <TextBlock Name="txtblk"
                   Canvas.Left="100" Canvas.Top="100"
                   Text="ROTATE">
            <TextBlock.Projection>
                <PlaneProjection x:Name="planeProjection"
                                 CenterOfRotationX="0.5" CenterOfRotationY="0.5"
                                 RotationZ="45"/>
            </TextBlock.Projection>
        </TextBlock>
    </Canvas>
</Grid>

The TextBlock just disappeared! There is no other control in the page.

Could anyone tell me what happened? I'm really stuck.

Thanks!

P.S. The full xaml is as below:

<phone:PhoneApplicationPage 
x:Class="WP7Test.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="728" d:DesignHeight="480"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Landscape" Orientation="Landscape"
shell:SystemTray.IsVisible="False">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Canvas>
                <TextBlock Name="txtblk"
                           Canvas.Left="100" Canvas.Top="100"
                           Text="ROTATE">
                    <TextBlock.Projection>
                        <PlaneProjection x:Name="planeProjection"
                                         CenterOfRotationX="0.5"
                                         CenterOfRotationY="0.5"
                                         RotationZ="45"/>
                    </TextBlock.Projection>
                </TextBlock>
            </Canvas>
        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

Solution

  • If I run a Silverlight example of the same thing, Projection Transforms Sans Math, the effect works correctly in Silverlight. If I copy and paste the XAML from that project into a phone project then the projection renders properly on the phone. If I paste your code into Silverlight it works fine in Silverlight. If I trim the odd nested grid out of your code it still works in Silverlight, but continues to fail on the phone. If I remove the Canvas element from the phone version and remove the Canvas.Top and Canvas.Left attached properties then it works on the phone.

    Based on those experiments, I think that this looks like a bug and if its not a bug there is no mention of the limitation anywhere that I can find.

    The simple workaround is to apply the Projection to a StackPanel, Viewbox or similar UIElement container.

    Here's an example:

    <Grid x:Name="LayoutRoot" Background="Transparent" ShowGridLines="True">
        <Canvas Background="Purple">
            <Viewbox Canvas.Left="100" Canvas.Top="100" >
                <Viewbox.Projection>
                    <PlaneProjection x:Name="planeProjection" CenterOfRotationX="0.5" CenterOfRotationY="0.5" RotationZ="45"/>
                </Viewbox.Projection>
                <TextBlock Name="txtblk" Text="ROTATE" FontSize="288"/>
            </Viewbox>
        </Canvas>
    </Grid>