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日