有時候使用Visual Studio 2010開啟以Expression Blend產出的XAML檔要進行編輯的時候,會發生出現Exception的情況;而從錯誤訊息中只能依稀的判斷出是Reflection無法解析出某個屬性,但是在Expression Blend中開啟同一個檔案卻又是正常的,而且不管是用Visual Studio 2010或是Expression Blend進行編譯後也都能順利的執行,這時候千萬別怪罪辛苦的設計人員,並不是他們把XAML搞爛的,而且這種情況是有解的。
日前在MSDN論壇遇到有人問到在WPF的Ellipse中使用ImageBrush做為筆刷,並且將ImageBrush套用TranslateTransform的時候,ImageBrush的顯示可能會有問題,所以我就自己動手在Blend裡面也拉了一個小Sample,來看看這個問題到底是怎麼發生的。
如果我們直接透過Belnd將ImageBrush的TranslateTransform中的X與Y屬性值都設為1的話,會發生下圖的情況:咦!?我只是位移一個Pixel而已,怎麼整張圖都不見啦 !?(根據實測,Silverlight也會有類似的情況)
經過檢查透過Blend自動產生的XAML之後,發現原來兇手就是RelativeTransform,但是偏偏Blend裡面預設的Transform都會自動視為RelativeTransform,而ImageBrush如果在RelativeTransform中套用了TranslateTransform的話,就會發生上圖的現象(還真是饒舌 )。
那如果就是要在ImageBrush中套用TranslateTransform的解法呢?很簡單,只要讓TranslateTransform獨立於RelativeTransform之外就好啦!!
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>