[Silverlight][WPF] 解決ImageBrush的TranslateTransform無法正確顯示的現象

  • 6477
  • 0
  • RIA
  • 2013-07-14

日前在MSDN論壇遇到有人問到在WPF的Ellipse中使用ImageBrush做為筆刷,並且將ImageBrush套用TranslateTransform的時候,ImageBrush的顯示可能會有問題,所以我就自己動手在Blend裡面也拉了一個小Sample,來看看這個問題到底是怎麼發生的。

 

日前在MSDN論壇遇到有人問到在WPF的Ellipse中使用ImageBrush做為筆刷,並且將ImageBrush套用TranslateTransform的時候,ImageBrush的顯示可能會有問題,所以我就自己動手在Blend裡面也拉了一個小Sample,來看看這個問題到底是怎麼發生的。

 

我在Blend中拉出來的介面如下:

image

 

如果我們直接透過Belnd將ImageBrush的TranslateTransform中的X與Y屬性值都設為1的話,會發生下圖的情況:咦!?我只是位移一個Pixel而已,怎麼整張圖都不見啦疑惑!?(根據實測,Silverlight也會有類似的情況)

image

 

經過檢查透過Blend自動產生的XAML之後,發現原來兇手就是RelativeTransform,但是偏偏Blend裡面預設的Transform都會自動視為RelativeTransform,而ImageBrush如果在RelativeTransform中套用了TranslateTransform的話,就會發生上圖的現象(還真是饒舌吐舌頭)。

那如果就是要在ImageBrush中套用TranslateTransform的解法呢?很簡單,只要讓TranslateTransform獨立於RelativeTransform之外就好啦!!

 

修改後的XAML如下:

Page1.xaml

<Page x:Class="Wpf_ImageBrushTranslate.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="640" Width="Auto"
        Height="Auto" Title="Page1">
    <Border CornerRadius="10" BorderBrush="#FF323232" BorderThickness="2">

        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="111" />
            </Grid.RowDefinitions>
            <Grid Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.103*" />
                    <RowDefinition Height="0.897*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.5*" />
                    <ColumnDefinition Width="0.5*" />
                </Grid.ColumnDefinitions>
                <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="預設的Transform" d:LayoutOverrides="Height" VerticalAlignment="Center"
                        FontSize="18.667" />
                <WrapPanel Margin="10" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1">
                    <Ellipse Height="250" Stroke="Black" Width="250" Margin="10">
                        <Ellipse.Fill>
                            <ImageBrush ImageSource="PicOfWeek.jpg" Stretch="UniformToFill">
                                <ImageBrush.RelativeTransform>
                                    <TransformGroup>
                                        <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="{Binding Value, ElementName=sldScale}"
                                                ScaleY="{Binding Value, ElementName=sldScale}" />
                                        <SkewTransform CenterX="0.5" CenterY="0.5" />
                                        <RotateTransform CenterX="0.5" CenterY="0.5" Angle="{Binding Value, ElementName=sldRotate}" />
                                        <TranslateTransform X="{Binding Value, ElementName=sldTranslate}"
                                                Y="{Binding Value, ElementName=sldTranslate}" />
                                    </TransformGroup>
                                </ImageBrush.RelativeTransform>
                            </ImageBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                </WrapPanel>
                <TextBlock Grid.Column="1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="修改過的Transform" VerticalAlignment="Center"
                        FontSize="18.667" />
                <WrapPanel Grid.Column="1" Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1">
                    <Ellipse Height="250" Stroke="Black" Width="250" Margin="10">
                        <Ellipse.Fill>
                            <ImageBrush ImageSource="PicOfWeek.jpg" Stretch="UniformToFill">
                                <ImageBrush.RelativeTransform>
                                    <TransformGroup>
                                        <ScaleTransform ScaleY="{Binding Value, ElementName=sldScale}" ScaleX="{Binding Value, ElementName=sldScale}"
                                                CenterX="0.5" CenterY="0.5" />
                                        <SkewTransform CenterX="0.5" CenterY="0.5" />
                                        <RotateTransform Angle="{Binding Value, ElementName=sldRotate}" CenterX="0.5" CenterY="0.5" />
                                        <TranslateTransform />
                                    </TransformGroup>
                                </ImageBrush.RelativeTransform>
                                <ImageBrush.Transform>
                                    <TranslateTransform x:Name="translate1" X="{Binding Value, ElementName=sldTranslate}"
                                            Y="{Binding Value, ElementName=sldTranslate}" />
                                </ImageBrush.Transform>
                            </ImageBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                </WrapPanel>
            </Grid>
            <StackPanel Margin="10,0,0,0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
                <StackPanel Orientation="Horizontal" Margin="0,2">
                    <TextBlock TextWrapping="Wrap" Text="ScaleTransform" VerticalAlignment="Center" Width="120" TextAlignment="Right" />
                    <Slider x:Name="sldScale" Width="300" Margin="10,0,0,0" SmallChange="1" Value="1" Minimum="1" TickPlacement="BottomRight"
                            Maximum="5" IsSnapToTickEnabled="True" />
                    <TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Width="40" TextAlignment="Right"
                            Text="{Binding Value, ElementName=sldScale}" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" Margin="0,2">
                    <TextBlock TextWrapping="Wrap" Text="RotateTransform" VerticalAlignment="Center" Width="120" TextAlignment="Right" />
                    <Slider x:Name="sldRotate" Width="300" Margin="10,0,0,0" Maximum="360" SmallChange="1" IsSnapToTickEnabled="True" />
                    <TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Width="40" TextAlignment="Right"
                            Text="{Binding Value, ElementName=sldRotate}" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" Margin="0,2">
                    <TextBlock TextWrapping="Wrap" Text="TranslateTransform" VerticalAlignment="Center" Width="120" TextAlignment="Right" />
                    <Slider x:Name="sldTranslate" Width="300" Margin="10,0,0,0" Maximum="50" SmallChange="1" TickPlacement="BottomRight"
                            IsSnapToTickEnabled="True" />
                    <TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Width="40" TextAlignment="Right"
                            Text="{Binding Value, ElementName=sldTranslate}" />
                </StackPanel>
            </StackPanel>
        </Grid>
    </Border>
</Page>

 

就這麼簡單,來看看改完的結果吧!!

(*若無法正常瀏覽本WPF版範例,煩請參考[Windows7]使用IE9、FireFox與Chrome瀏覽WPF Browser Application(.XBAP)的方式一文調整瀏覽器設定)

 

最後一樣奉上原始碼,請自行服用: