WPF中文网

VisualBrush放大镜+水印文字

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日

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1