[WPF] VisualBrush 中的布局

摘要:
笔者今天说的是第二种方案:VisualBrush、这个强大的Brush类,它可以将任意Visual元素转化为Brush。最终代码:最终代码当然,代码还是不够完美:由于背景区域的大小不固定,所以设置了一个超大的宽高。问题解决了,再回头看一下VisualBrush中的布局、由于VisualBursh中的Visual的父级是VisualBrush,它不能为Visual中的根元素提供大小,因此如果应用了Stretch="None",那么就需要手动设置Visual根元素的大小了。

今天插一篇随笔。说一说上周五遇到的一个布局问题,问题大概是这样的:需要在一个快区域上添加一张透明的背景图片,由于区域较大、并且宽高都不是固定大小,图片较小 所以图片需要居中显示。除此之外还需要在图片的透明部分添加一个非透明的纯色。

比如:最终的效果图、如下图所示:
[WPF] VisualBrush 中的布局第1张

当然如果只是为了实现这种效果、实现方案有多种,至少有三大类:

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的宽高都失效了):

[WPF] VisualBrush 中的布局第2张

看到这个效果、我的第一直觉是在 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>
修改后的代码

事实再一次出乎意料:

[WPF] VisualBrush 中的布局第3张

表现出来的形式: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上也可以得到证实。

免责声明:文章转载自《[WPF] VisualBrush 中的布局》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用Ingress来负载分发微服务给折腾ramdisk的朋友们一点建议下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WPF绑定错误

listbox绑定遇到了奇怪的报错如下: System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl'...

background:url 的使用方法

1 #pingfen li{ 2 27px; 3 float:left; 4 height:28px; 5 cursor:pointer; 6 background:url('star.gif') no-repeat 0 0; 7 list-style:none; 8 } bac...

less一些用法整理

前提理解:第一个,less是单独的一种文件,可以理解为css的升级版,完全按照css写也没问题,不过它提供了很多便利的东西,可以省好多代码量。第二个,html只认css,所以需要配套一些软件将less解析成css,引用时候,直接引用css就好。gulp,koala 都是常用的,Koala好像简单且方便一点。 嵌套 less的优势有很多,最常用也是最让人舒坦...

foobar2000 – ELPlaylist

布局抄自MonoLite_Plus_0_4_3_by_Junior_Spirit,皮肤也是用的他的 Track List: //背景颜色 播放、播放+焦点、焦点、奇偶 $if(%el_isplaying%,   $if(%el_focused%,$puts(backgroung_color,%B_color_PF%),$puts(backgroung_c...

WPF模式思考 (zt)

Introduction Since XAML things have become a bit complicated in trying to conceptualize MVC architectures for Windows applications. The gap between web and win is narrowing and th...

WPF多语言化的实现

  Metro插件系统系列就暂时停一下,这次我们讨论一下WPF的资源本地化实现,主要用到的:CultureInfo,ResourceManger,MarkupExtension,RESX文件,这些都是.NET框架提供的。 项目结构: 运行结果: 可在程序运行时,实时切换语言 CultureInfo   CultureInfo类表示有关特定区域性的信息...