[WPF] VisualBrush 中的布局

原文:[WPF] VisualBrush 中的布局

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

比如:最终的效果图、如下图所示:

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

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 上也可以得到证实。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9665338.html

时间: 2024-10-09 01:49:39

[WPF] VisualBrush 中的布局的相关文章

WPF中Grid布局

WPF中Grid布局XMAl与后台更改,最普通的登录界面为例. <Grid Width="200" Height="100" > <!--定义了两列--> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="100*"/> </Grid.Column

WPF实现界面动态布局

以前总觉得动态布局是个很麻烦的问题,是个很需要功力的问题.但是貌似在.NET中,在WPF中却不是那么的麻烦.下面介绍我现在实现的一个动态布局的实例. 因为有需求,所以困难得克服!而我们的需求表名,不同的用户需要的界面元素是不一样的,我们总不能每次都去修改代码吧!所以,需要完成动态布局. 这里主要完成这样一个功能: 1.动态画线 2.动态new控件 3.线和控件都是可拖拽并随意放置位置的 4.线和控件是可删除的 5.控件是可绑定属性和事件的 要完成这样的功能,我们首先得定义三个鼠标事件,即:左键d

WPF入门——XAML和布局容器

WPF是微软推出的基于Windows Vista的用户界面框架:它提供了统一的编程模型.语言和框架,真正做到了分离界面设计人员与开发人员的工作.WPF和.NET中winForm是类似的. XAML 1.XAML是对WPF程序的所用用户界面进行详细的定制. 2.它提供了一种便于扩展和定位的语法来定义和程序逻辑分离的用户界面,而这种实现方式和ASP.NET中的"代码后置"模型非常类似. 3.但是XAML并不是一种用于程序设计的语言,它的功能也不是为了执行应用程序逻辑. 4.说的通俗一点,W

WPF笔记(1.4 布局)——Hello,WPF!

原文:WPF笔记(1.4 布局)--Hello,WPF! 这一节只是第2章的引子.布局要使用Panel控件,有四种Panel,如下:DockPanel,就是设置停靠位置布局模型.StackPanel,提供一个从左至右或从上至下放置内容的堆栈模型.Grid,提供一个允许进行 行/网格定位的模型.可使用表格.Canvas,可精确定位. 其中,Grid是最常用的,vs2005自动生成的Page和window都默认带有这个标签: Example 1-25. A sample usage of the G

组件在容器中的布局

1,FlowLayout管理器 流式布局管理器,组件按照从左到右的流式顺序布局,JPanel组件中的默认布局管理器. 2,BorderLayout管理器 边框布局管理器,将容器分为东西南北中五个区域,每个区域只能添加一个组件,该组件的大小由其所在的区域决定.它是JFrame中的默认布局管理器. 3,GridLayout管理器 网格布局管理器,将容器分为行列的网格. 4,BoxLayout管理器 盒式布局管理器,组件安装垂直或者水平方式显示. 组件在容器中的布局,码迷,mamicode.com

WPF 程序中启动和关闭外部.exe程序

当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; u

无废话Android之常见adb指令、电话拨号器、点击事件的4种写法、短信发送器、Android 中各种布局(1)

1.Android是什么 手机设备的软件栈,包括一个完整的操作系统.中间件.关键的应用程序,底层是linux内核,安全管理.内存管理.进程管理.电源管理.硬件驱动 2.Dalvik VM 和 JVM 的比较 3.常见adb指令 platform-tools/adb.exe adb.exe : android debug bridge android调试桥 adb devices:列出所以连接的设备 adb kill-server :杀死adb调试桥 adb start-server :启动adb

Java中用户界面布局

绝对布局Absolute 通过放大或缩小界面的时候,组件大小和位置不会发生变化 浮动布局FlowLayout 调整应用程序窗口的大小时,组件将立刻重新排列 边界布局Border Layout 该位置有5个方位:东.南.西.北.中 网格布局Grid Layout 如需要将大量组件按规律排列,那么网格布局是最合适的,比如计算器界面的制作. CardLayout     卡片布局和其他布局不同,因为它隐藏了一些组件.卡片布局就是一组容器或者组件,它们一次仅仅显是一个,组中的每个容器称为卡片.   分组

wpf 窗体中显示当前系统时间

先看一下效果: 这其实是我放置了两个TextBlock,上面显示当前的日期,下面显示时间. 接下来展示一下代码: 在XAML中: <StackPanel Width="205"                    Margin="0,0,57,0"                    HorizontalAlignment="Right">            <TextBlock Height="Auto&qu