在进行WPF界面设计时,我们需要在很多地方设置颜色属性,比如元素的背景色、前景色以及边框的颜色,还有形状的内部填充和笔画,这些颜色的设置在WPF中都以画刷(Brush)的形式实现。比如最常用的画刷就是SolidColorBrush,它表示一种纯色。
画刷被定义成一个抽象类,如下所示。
public abstract class Brush : Animatable, IFormattable, IResource
{
public static readonly DependencyProperty OpacityProperty;
public static readonly DependencyProperty TransformProperty;
public static readonly DependencyProperty RelativeTransformProperty;
protected Brush();
public double Opacity { get; set; }
public Transform Transform { get; set; }
public Transform RelativeTransform { get; set; }
public Brush Clone();
public Brush CloneCurrentValue();
public override string ToString();
public string ToString(IFormatProvider provider);
}
Brush继承于Animatable基类和Freezable基类,说明它支持更改通知。如果改变了画刷,任何使用该画刷的控件的颜色都会自动重绘。
Opacity 属性表示它支持部分透明。
Brush一共有7个子类,下表中列出了它们的信息。
画刷名称 | 功能说明 |
SolidColorBrush | 使用单一的连续颜色填充区域 |
LinearGradientBrush | 使用线性渐变绘制区域。 |
RadialGradientBrush | 使用径向渐变绘制区域。 焦点定义渐变的开始,而圆定义渐变的终点。 |
ImageBrush | 使用图像绘制区域。 |
VisualBrush | 使用一个视图绘制区域。 |
BitmapCacheBrush | 绘制带有缓存的内容的区域。 |
DrawingBrush | 使用包括形状、文本、视频、图像或其他绘制项等填充区域。 |
关于Brush基类和子类的继承关系,参考下图所示。
另外,WPF还定义了一些默认画刷,这些画刷都被定义在Brushes类中。如下所示
public sealed class Brushes
{
public static SolidColorBrush AliceBlue { get; }
public static SolidColorBrush PaleGoldenrod { get; }
public static SolidColorBrush Orchid { get; }
public static SolidColorBrush OrangeRed { get; }
public static SolidColorBrush Orange { get; }
public static SolidColorBrush OliveDrab { get; }
public static SolidColorBrush Olive { get; }
public static SolidColorBrush OldLace { get; }
public static SolidColorBrush Navy { get; }
public static SolidColorBrush NavajoWhite { get; }
public static SolidColorBrush Moccasin { get; }
public static SolidColorBrush MistyRose { get; }
public static SolidColorBrush MintCream { get; }
public static SolidColorBrush MidnightBlue { get; }
public static SolidColorBrush MediumVioletRed { get; }
public static SolidColorBrush MediumTurquoise { get; }
public static SolidColorBrush MediumSpringGreen { get; }
public static SolidColorBrush MediumSlateBlue { get; }
public static SolidColorBrush LightSkyBlue { get; }
public static SolidColorBrush LightSlateGray { get; }
public static SolidColorBrush LightSteelBlue { get; }
public static SolidColorBrush LightYellow { get; }
public static SolidColorBrush Lime { get; }
public static SolidColorBrush LimeGreen { get; }
public static SolidColorBrush PaleGreen { get; }
public static SolidColorBrush Linen { get; }
public static SolidColorBrush Maroon { get; }
public static SolidColorBrush MediumAquamarine { get; }
public static SolidColorBrush MediumBlue { get; }
public static SolidColorBrush MediumOrchid { get; }
public static SolidColorBrush MediumPurple { get; }
public static SolidColorBrush MediumSeaGreen { get; }
public static SolidColorBrush Magenta { get; }
public static SolidColorBrush PaleTurquoise { get; }
public static SolidColorBrush PaleVioletRed { get; }
public static SolidColorBrush PapayaWhip { get; }
public static SolidColorBrush SlateGray { get; }
public static SolidColorBrush Snow { get; }
public static SolidColorBrush SpringGreen { get; }
public static SolidColorBrush SteelBlue { get; }
public static SolidColorBrush Tan { get; }
public static SolidColorBrush Teal { get; }
public static SolidColorBrush SlateBlue { get; }
public static SolidColorBrush Thistle { get; }
public static SolidColorBrush Transparent { get; }
public static SolidColorBrush Turquoise { get; }
public static SolidColorBrush Violet { get; }
public static SolidColorBrush Wheat { get; }
public static SolidColorBrush White { get; }
public static SolidColorBrush WhiteSmoke { get; }
public static SolidColorBrush Tomato { get; }
public static SolidColorBrush LightSeaGreen { get; }
public static SolidColorBrush SkyBlue { get; }
public static SolidColorBrush Sienna { get; }
public static SolidColorBrush PeachPuff { get; }
public static SolidColorBrush Peru { get; }
public static SolidColorBrush Pink { get; }
public static SolidColorBrush Plum { get; }
public static SolidColorBrush PowderBlue { get; }
public static SolidColorBrush Purple { get; }
public static SolidColorBrush Silver { get; }
public static SolidColorBrush Red { get; }
public static SolidColorBrush RoyalBlue { get; }
public static SolidColorBrush SaddleBrown { get; }
public static SolidColorBrush Salmon { get; }
public static SolidColorBrush SandyBrown { get; }
public static SolidColorBrush SeaGreen { get; }
public static SolidColorBrush SeaShell { get; }
public static SolidColorBrush RosyBrown { get; }
public static SolidColorBrush Yellow { get; }
public static SolidColorBrush LightSalmon { get; }
public static SolidColorBrush LightGreen { get; }
public static SolidColorBrush DarkRed { get; }
public static SolidColorBrush DarkOrchid { get; }
public static SolidColorBrush DarkOrange { get; }
public static SolidColorBrush DarkOliveGreen { get; }
public static SolidColorBrush DarkMagenta { get; }
public static SolidColorBrush DarkKhaki { get; }
public static SolidColorBrush DarkGreen { get; }
public static SolidColorBrush DarkGray { get; }
public static SolidColorBrush DarkGoldenrod { get; }
public static SolidColorBrush DarkCyan { get; }
public static SolidColorBrush DarkBlue { get; }
public static SolidColorBrush Cyan { get; }
public static SolidColorBrush Crimson { get; }
public static SolidColorBrush Cornsilk { get; }
public static SolidColorBrush CornflowerBlue { get; }
public static SolidColorBrush Coral { get; }
public static SolidColorBrush Chocolate { get; }
public static SolidColorBrush AntiqueWhite { get; }
public static SolidColorBrush Aqua { get; }
public static SolidColorBrush Aquamarine { get; }
public static SolidColorBrush Azure { get; }
public static SolidColorBrush Beige { get; }
public static SolidColorBrush Bisque { get; }
public static SolidColorBrush DarkSalmon { get; }
public static SolidColorBrush Black { get; }
public static SolidColorBrush Blue { get; }
public static SolidColorBrush BlueViolet { get; }
public static SolidColorBrush Brown { get; }
public static SolidColorBrush BurlyWood { get; }
public static SolidColorBrush CadetBlue { get; }
public static SolidColorBrush Chartreuse { get; }
public static SolidColorBrush BlanchedAlmond { get; }
public static SolidColorBrush DarkSeaGreen { get; }
public static SolidColorBrush DarkSlateBlue { get; }
public static SolidColorBrush DarkSlateGray { get; }
public static SolidColorBrush HotPink { get; }
public static SolidColorBrush IndianRed { get; }
public static SolidColorBrush Indigo { get; }
public static SolidColorBrush Ivory { get; }
public static SolidColorBrush Khaki { get; }
public static SolidColorBrush Lavender { get; }
public static SolidColorBrush Honeydew { get; }
public static SolidColorBrush LavenderBlush { get; }
public static SolidColorBrush LemonChiffon { get; }
public static SolidColorBrush LightBlue { get; }
public static SolidColorBrush LightCoral { get; }
public static SolidColorBrush LightCyan { get; }
public static SolidColorBrush LightGoldenrodYellow { get; }
public static SolidColorBrush LightGray { get; }
public static SolidColorBrush LawnGreen { get; }
public static SolidColorBrush LightPink { get; }
public static SolidColorBrush GreenYellow { get; }
public static SolidColorBrush Gray { get; }
public static SolidColorBrush DarkTurquoise { get; }
public static SolidColorBrush DarkViolet { get; }
public static SolidColorBrush DeepPink { get; }
public static SolidColorBrush DeepSkyBlue { get; }
public static SolidColorBrush DimGray { get; }
public static SolidColorBrush DodgerBlue { get; }
public static SolidColorBrush Green { get; }
public static SolidColorBrush Firebrick { get; }
public static SolidColorBrush ForestGreen { get; }
public static SolidColorBrush Fuchsia { get; }
public static SolidColorBrush Gainsboro { get; }
public static SolidColorBrush GhostWhite { get; }
public static SolidColorBrush Gold { get; }
public static SolidColorBrush Goldenrod { get; }
public static SolidColorBrush FloralWhite { get; }
public static SolidColorBrush YellowGreen { get; }
}
这些画刷都位于System.Windows.Media。
从下一节开始,我们就逐一讲解这些画刷的使用。
——重庆教主 2023年11月3日
SolidColorBrush继承于Brush抽象类,表示用某一种颜色填充区域。从定义上看,它拥有一个Color属性,表示具体的颜色值。
public sealed class SolidColorBrush : Brush
{
public static readonly DependencyProperty ColorProperty;
public SolidColorBrush();
public SolidColorBrush(Color color);
public Color Color { get; set; }
public static object DeserializeFrom(BinaryReader reader);
public SolidColorBrush Clone();
public SolidColorBrush CloneCurrentValue();
}
Color 在WPF中代表颜色值,被设计成一个结构体,主要是4个属性,即A、R、G、B,分别表示Alpha透明通道值,红色通道值、绿色通道值和蓝色通道值。它们的取值范围都是0-255。
所以假如我们要设置Grid的背景颜色,在XAML中可以如下设置
<Grid>
<Grid.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="255" R="255" G="0" B="0"/>
</SolidColorBrush.Color>
</SolidColorBrush>
</Grid.Background>
</Grid>
当然,还有更简单的方法。就是使用系统颜色。
<Grid Background="Red">
<!--<Grid.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="255" R="255" G="0" B="0"/>
</SolidColorBrush.Color>
</SolidColorBrush>
</Grid.Background>-->
</Grid>
两种方式,结果都会以红色填充Grid区域。需要注意的是,两种方式不可同时使用,所以我将其中一种方式注释掉了。
我们还可以用C#代码的方式去设置背景颜色。
SolidColorBrush solidColorBrush = new SolidColorBrush();
//使用系统自定义的颜色
solidColorBrush.Color = Colors.Green;
//或者从Color的FromRgb成员中得到颜色
solidColorBrush.Color = Color.FromRgb(0, 0x80, 0);
grid.Background = solidColorBrush;
我们在构造函数中将grid的颜色设置为绿色,如下所示。
虽然在XAML中,当前Grid的背景颜色初始值是红色,但是我们在运行时将其改成了绿色。通常,它还可以被实例化成一个资源,这样达到一次定义多次使用的效果。
<Window.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="#123456"/>
</Window.Resources>
<Grid x:Name="grid" Background="{StaticResource BackgroundBrush}"/>
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:094-《SolidColorBrush纯色画刷》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
——重庆教主 2023年11月03日
一、概念
LinearGradientBrush是一个比较有意思的画刷,它可以从一种颜色过渡到另一种颜色,使被填充的区域呈现渐变效果。
public sealed class LinearGradientBrush : GradientBrush
{
public static readonly DependencyProperty StartPointProperty;
public static readonly DependencyProperty EndPointProperty;
public LinearGradientBrush();
public LinearGradientBrush(GradientStopCollection gradientStopCollection);
public LinearGradientBrush(GradientStopCollection gradientStopCollection, double angle);
public LinearGradientBrush(Color startColor, Color endColor, double angle);
public LinearGradientBrush(GradientStopCollection gradientStopCollection, Point startPoint, Point endPoint);
public LinearGradientBrush(Color startColor, Color endColor, Point startPoint, Point endPoint);
public Point StartPoint { get; set; }
public Point EndPoint { get; set; }
public LinearGradientBrush Clone();
public LinearGradientBrush CloneCurrentValue();
}
从定义上看,它有StartPoint 和EndPoint 两个点,表示获取和设置线性渐变的二维起始坐标和结束坐标。而它因为继承于GradientBrush基类,所以它的颜色都保存在GradientStops集合属性中。GradientStops集合中的元素类型必须为GradientStop,表示渐变中转换点的位置和颜色。所以,GradientStop拥有Color属性和Offset属性,分别表示颜色值和偏移值。
例如,我们有一个Grid,希望从左上角设置一个绿色,右下角设置一个蓝色,中间是两种颜色的渐变效果。那么,就可以在XAML中如下设置。
<Grid>
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Green" Offset="0"/>
<GradientStop Color="Blue" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
</Grid>
LinearGradientBrush将整个Grid看成是一个0-1的矩形,所以StartPoint=(0,0)表示左上角,EndPoint=(1,1)表示右下角,这就控制了渐变的方向是从左上角到右下角的斜线。GradientStop 对象中的Offset表示在渐变方向上各颜色的占比或起点。假如我们将第一个GradientStop对象的Offset设置为0.5,那么此时的代码和效果如下所示:
<Grid>
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Green" Offset="0.5"/>
<GradientStop Color="Blue" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
</Grid>
事实上,绿色占据了整个填充区域50%,并从50%处开始向蓝色进行渐变。根据LinearGradientBrush 画刷的特色,接下来,我们来做一个有趣的例子。
前端代码
<Window x:Class="HelloWorld.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorld"
xmlns:controls="clr-namespace:HelloWorld.Controls"
xmlns:helper="clr-namespace:HelloWorld.MVVM"
mc:Ignorable="d" MouseMove="Window_MouseMove"
Title="WPF中文网 - www.wpfsoft.com" Height="350" Width="500">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid x:Name="grid">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Green" Offset="0.5"/>
<GradientStop Color="Blue" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<TextBlock x:Name="textblock"
Text="渐变色课程"
FontSize="50"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock.Foreground>
<LinearGradientBrush>
<GradientStop Color="Gold" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="LightPink" Offset="1"/>
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</Window>
后端代码
private void Window_MouseMove(object sender, MouseEventArgs e)
{
var gridBrush = grid.Background as LinearGradientBrush;
GradientStop gradientStop0 = gridBrush.GradientStops[0];
GradientStop gradientStop1 = gridBrush.GradientStops[1];
Point point = e.GetPosition(this);
double offset = (point.X + point.Y) / (this.Width + this.Height);
gradientStop0.Offset = offset;
gradientStop1.Offset = 1 - offset;
}
我们可以获取鼠标在当前窗口中的位置,转换成一个offset值,将它赋值给LinearGradientBrush的GradientStop 对象中的Offset 属性。F5运行调试,Grid的背景渐变颜色的偏移位置将随鼠标移动而变化。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:095-《LinearGradientBrush渐变画刷》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
——重庆教主 2023年11月03日
一、概念
RadialGradientBrush径向渐变像一个圆一样,从焦点中心位置开始向四周渐变,LinearGradientBrush线性渐变具有用于定义渐变矢量的起点和终点,而径向渐变具有一个圆和一个焦点,用于定义渐变行为。 圆定义渐变的终点。 换句话说,渐变停止点为 1.0 定义圆周的颜色。 焦点定义渐变的中心。 渐变停止点为 0.0 定义焦点处的颜色。
public sealed class RadialGradientBrush : GradientBrush
{
public static readonly DependencyProperty CenterProperty;
public static readonly DependencyProperty RadiusXProperty;
public static readonly DependencyProperty RadiusYProperty;
public static readonly DependencyProperty GradientOriginProperty;
public RadialGradientBrush();
public RadialGradientBrush(GradientStopCollection gradientStopCollection);
public RadialGradientBrush(Color startColor, Color endColor);
public Point Center { get; set; }
public double RadiusX { get; set; }
public double RadiusY { get; set; }
public Point GradientOrigin { get; set; }
public RadialGradientBrush Clone();
public RadialGradientBrush CloneCurrentValue();
}
Center属性:获取或设置径向渐变的最外面圆的中心。
RadiusX属性:获取或设置径向渐变的最外面圆的水平半径。默认值为 0.5。
RadiusY属性:获取或设置径向渐变的最外面圆的垂直半径。默认值为 0.5。
GradientOrigin属性:获取或设置用于定义渐变开始的二维焦点的位置。默认值为 0.5。
我们以Ellipse控件为例,演示一下RadialGradientBrush 的用法。
<Grid x:Name="grid">
<Ellipse Width="200" Height="200">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.5,0.5"
RadiusX="0.75"
RadiusY="0.75">
<RadialGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Black" Offset="0.65" />
<GradientStop Color="Gray" Offset="0.8" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
在上面的代码中,处于圆中心的白色渐变点由GradientOrigin属性控制,如果将值改成:GradientOrigin="0.25,0.25",那么它会呈现下面的样子。
根据这个特性,我们可以实现一个有趣的示例。那就是当鼠标移动到椭圆内,这个径向渐变的起点坐标跟随鼠标位置变化而变化。
前端代码
<Window x:Class="HelloWorld.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorld"
xmlns:controls="clr-namespace:HelloWorld.Controls"
xmlns:helper="clr-namespace:HelloWorld.MVVM"
mc:Ignorable="d"
Title="WPF中文网 - www.wpfsoft.com" Height="350" Width="500">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid x:Name="grid">
<Ellipse x:Name="ellipse"
Width="200"
Height="200"
MouseMove="ellipse_MouseMove">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.25,0.25"
RadiusX="0.75"
RadiusY="0.75">
<RadialGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Goldenrod" Offset="0.65" />
<GradientStop Color="Gray" Offset="0.8" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Window>
这次我们改一下渐变颜色,让它看起来像是一个发光的太阳。
我们为Ellipse 对象的MouseMove事件订阅了一个回调函数。下面看看在回调函数中的业务代码。
private void ellipse_MouseMove(object sender, MouseEventArgs e)
{
Ellipse ellipse = e.Source as Ellipse;
Point point = e.GetPosition(ellipse);
double width = ellipse.Width;
double height = ellipse.Height;
RadialGradientBrush brush = ellipse.Fill as RadialGradientBrush;
double x = point.X / width;
double y = point.Y / height;
brush.GradientOrigin = new Point(x, y);
}
首先,我们获取当前Ellipse 对象和当前鼠标位置,然后计算GradientOrigin 的x轴方向 和y轴方向的点,最后更新RadialGradientBrush 的GradientOrigin 即可。接下来,F5运行调试一下,您会看到一个不错的特效( ^_^ )。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:096-《RadialGradientBrush径向渐变》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
重庆教主 2023年11月03日
ImageBrush表示使用图像绘制区域。它继承于TileBrush抽象基类,另外,DrawingBrush和VisualBrush也继承于TileBrush抽象基类。
一、TileBrush抽象基类
TileBrush 有三种不同类型,其中每一种都使用不同类型的内容进行绘制。下面列出它3个子类的情况。
- 若使用ImageBrush子类,则画刷的填充内容是图像;
- 若使用DrawingBrush子类,则画刷的填充内容是绘图;
- 若使用VisualBrush子类,则画刷的填充内容是视觉对象(视觉树或控件);
public abstract class TileBrush : Brush
{
public static readonly DependencyProperty ViewportUnitsProperty;
public static readonly DependencyProperty ViewboxUnitsProperty;
public static readonly DependencyProperty ViewportProperty;
public static readonly DependencyProperty ViewboxProperty;
public static readonly DependencyProperty StretchProperty;
public static readonly DependencyProperty TileModeProperty;
public static readonly DependencyProperty AlignmentXProperty;
public static readonly DependencyProperty AlignmentYProperty;
protected TileBrush();
public TileMode TileMode { get; set; }
public Stretch Stretch { get; set; }
public Rect Viewbox { get; set; }
public Rect Viewport { get; set; }
public AlignmentY AlignmentY { get; set; }
public BrushMappingMode ViewportUnits { get; set; }
public AlignmentX AlignmentX { get; set; }
public BrushMappingMode ViewboxUnits { get; set; }
public TileBrush Clone();
public TileBrush CloneCurrentValue();
protected abstract void GetContentBounds(out Rect contentBounds);
}
TileMode 属性:获取或设置基本图块如何填充区域。枚举型,它一共有5个值,Tile表示在可用区域复制图像;FlipX表示复制图像但垂直翻转每个第二列;FlipY表示复制图像但水平翻转每个第二行;FlipXY表示复制图像,但是垂直翻转每个第二列,半水平翻转每个第二行。
Stretch 属性:获取或设置内容如何拉伸。
Viewbox 属性:获取或设置图块中内容的位置和尺寸。
Viewport 属性:获取或设置基本图块的位置和尺寸。它的类型是Rect,也就是用它来指定截取原图片的某个区域进行填充,这个区域的设置可以用绝对值和相对值两种方式设置,对应属性是ViewboxUnits,它有两个值,Absolute表示取绝对坐标,RelativeToBoundingBox表示取相对坐标。
AlignmentY属性:获取或设置基本图块的垂直对齐方式。
AlignmentX属性:获取或设置基本图块的垂直水平方式。
ViewboxUnits属性:获取或设置Viewbox的值是相对内容的边界框而言,还是绝对值。
ViewportUnits属性:获取或设置Viewport的值 是否是相对于输出区域的大小。
接下来,我们来看看ImageBrush的定义
public sealed class ImageBrush : TileBrush
{
public static readonly DependencyProperty ImageSourceProperty;
public ImageBrush();
public ImageBrush(ImageSource image);
public ImageSource ImageSource { get; set; }
public ImageBrush Clone();
public ImageBrush CloneCurrentValue();
protected override Freezable CreateInstanceCore();
protected override void GetContentBounds(out Rect contentBounds);
}
ImageBrush 画刷只需要设置它的ImageSource 属性,其它的属性都是从它的基类TileBrush继承而来。
下面的例子演示了ImageBrush 的用法。
前端代码
<Window x:Class="HelloWorld.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorld"
xmlns:controls="clr-namespace:HelloWorld.Controls"
xmlns:helper="clr-namespace:HelloWorld.MVVM"
mc:Ignorable="d"
MouseWheel="Window_MouseWheel"
Title="WPF中文网 - www.wpfsoft.com" Height="550" Width="500">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid x:Name="grid">
<Grid.Background>
<ImageBrush ImageSource="/Images/lyf.png"
Stretch="UniformToFill"
TileMode="Tile">
<ImageBrush.Viewport>
<Rect X="0" Y="0" Width="1" Height="1"/>
</ImageBrush.Viewport>
</ImageBrush>
</Grid.Background>
</Grid>
</Window>
在上面的代码中,我们给Grid控件设置了一个ImageBrush 图像画刷,并设置Stretch为UniformToFill,即自适应填充,同时设置了Viewport。那么它运行之后呈现的效果如下:
此时的Grid的背景其实就是一张图片。我们给Window对象的MouseWheel事件订阅了一个回调函数,并在其实改变了Viewport的宽度和高度。滚动鼠标的滚轮,此时Grid的背景图像的填充将会呈现如下的样子:
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
double offset = e.Delta / 3600.0;
ImageBrush imageBrush = grid.Background as ImageBrush;
Rect rect = imageBrush.Viewport;
if (rect.Width + offset <= 0 && rect.Height + offset <= 0)
return;
rect.Width += offset;
rect.Height += offset;
imageBrush.Viewport = rect;
}
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:097-《ImageBrush图像画刷》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
——重庆教主 2023年11月3日
VisualBrush表示可以用一个视觉树作为填充区域的“原材料”。这个类最主要的是Visual属性,它表示一个Visual对象。而WPF中所有的控件都继承自Visual基类,所以,原则上,所有的控件都可以成为某个区域的背景填充。
一、放大镜
接下来,我们以VisualBrush的特性制作一个放大镜和TextBox文框的水印文字效果。首先准备一张图。
我们将这张图导入到项目中,然后用Image控件将其加载到前端显示出来。然后在实例化一个Canvas对象,在其中画一个Ellipse图形,而图形的背景就用VisualBrush。如下所示。
<Window x:Class="HelloWorld.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorld" xmlns:controls="clr-namespace:HelloWorld.Controls"
xmlns:helper="clr-namespace:HelloWorld.Model"
mc:Ignorable="d"
Title="WPF从小白到大佬课程 - 画刷" Height="550" Width="500">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid x:Name="grid">
<Image x:Name="image"
Source="/Image/picture.png"
Stretch="Fill"
MouseMove="image_MouseMove"
MouseEnter="image_MouseEnter"
MouseLeave="image_MouseLeave"/>
<Canvas x:Name="canvas" IsHitTestVisible="False">
<Ellipse x:Name="ellipse"
Width="200"
Height="200"
StrokeThickness="1"
Stroke="Red">
<Ellipse.Fill>
<VisualBrush x:Name="visualBrush"
Visual="{Binding ElementName=image}"
ViewboxUnits="Absolute"/>
</Ellipse.Fill>
</Ellipse>
</Canvas>
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBox Width="390" Height="25" Margin="5">
<TextBox.Resources>
<VisualBrush x:Key="WaterText"
TileMode="None"
Opacity="0.3"
Stretch="None"
AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock Text="请输入画家或画名"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource WaterText}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource WaterText}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Content="搜索世界名画" Height="25" Margin="5"/>
</StackPanel>
</Grid>
</Window>
在Ellipse椭圆的背景中,我们实例化了一个VisualBrush,并将它的Visual绑定到Image 控件,这样椭圆的背景就是Image控件中的图像。然后我们给Image的MouseEnter、MouseLeave、MouseMove事件订阅了回调函数,主要是在鼠标移动的时候,根据当前鼠标的坐标位置,实时修改VisualBrush 的Viewbox属性以及Ellipse在Canvas中的相对位置,从而实现放大镜的效果。
后端代码如下:
private void image_MouseMove(object sender, MouseEventArgs e)
{
var point = e.GetPosition(image);//鼠标当前坐标
var length = ellipse.ActualWidth * 0.5;//放大镜半径
var radius = length / 2;
var viewboxRect = new Rect(point.X - radius, point.Y - radius, length, length);
visualBrush.Viewbox = viewboxRect;
ellipse.SetValue(Canvas.LeftProperty, point.X - ellipse.ActualWidth / 2);
ellipse.SetValue(Canvas.TopProperty, point.Y - ellipse.ActualHeight / 2);
}
private void image_MouseEnter(object sender, MouseEventArgs e)
{
ellipse.Visibility = Visibility.Visible;
}
private void image_MouseLeave(object sender, MouseEventArgs e)
{
ellipse.Visibility = Visibility.Collapsed;
}
二、水印文字
另外,我们在XAML前端代码中实例化了一个TextBox,并在TextBox的资源中定义了一个VisualBrush,于是,在TextBox的Style样式中,利用Trigger触发器,设置条件是当TextBox的Text为空时,就把VisualBrush显示到TextBox控件的背景上,从而实现水印效果。
那么,在设计XAML界面,它是下面这样子。
F5运行后,它是下面这个样子
上图中的椭圆将随着鼠标移动而移动,至于下面的TextBox控件,一旦用户输入值,水印将会消失。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:126-《VisualBrush放大镜+水印文字》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff
——重庆教主 2023年11月04日