今天插一篇随筆。說一說上周五遇到的一個布局問題,問題大概是這樣的:需要在一個快區域上添加一張透明的背景圖檔,由于區域較大、并且寬高都不是固定大小,圖檔較小 是以圖檔需要居中顯示。除此之外還需要在圖檔的透明部分添加一個非透明的純色。
比如:最終的效果圖、如下圖所示:

當然如果隻是為了實作這種效果、實作方案有多種,至少有三大類:
1、嵌套兩個控件、分别應用純色 和 居中圖像。
2、使用 VisualBrush 将組合效果應用在同一個控件的Background上
3、重寫控件、将組合效果繪制在Background上。
筆者今天說的是第二種方案:VisualBrush、這個強大的Brush類,它可以将任意Visual元素轉化為Brush。
筆者第一次寫的代碼如下:
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Border Grid.Row="1" Grid.Column="1">
<Border.Background>
<VisualBrush>
<VisualBrush.Visual>
<Border Background="#455C73">
<Image Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="img_xiaofangzi.png" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</Grid>
第一次寫的代碼
看樣子應該沒多大問題、可出現的效果卻不盡人意、圖像被拉伸了(并且Image的寬高都失效了):
看到這個效果、我的第一直覺是在 VisualBrush上應用: Stretch="None" :
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Border Grid.Row="1" Grid.Column="1">
<Border.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Border Background="#455C73">
<Image Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="img_xiaofangzi.png" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</Grid>
修改後的代碼
事實再一次出乎意料:
表現出來的形式:VisualBrush中的Border大小沒有填充整個背景色。 并且 Border的小大 和 Image的大小一緻,很像是Image的寬高 20 * 20 把 Border撐大了。
在嘗試為Broder設定寬高後,效果終于滿意了。最終代碼:
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Border Grid.Row="1" Grid.Column="1">
<Border.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Border Width="3000"
Height="3000"
Background="#455C73">
<Image Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="img_xiaofangzi.png" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</Grid>
最終代碼
當然,代碼還是不夠完美:由于背景區域的大小不固定,是以設定了一個超大的寬高。
問題解決了,再回頭看一下VisualBrush 中的布局、由于 VisualBursh中的Visual的父級是VisualBrush, 它不能為Visual中的根元素提供大小,是以如果應用了 Stretch="None" ,那麼就需要手動設定Visual根元素的大小了。這一點在
MSDN上也可以得到證明。