You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF C#实现ImageBrush鼠标悬停时局部区域同步放大效果

WPF图片跟随鼠标同步放大实现方案

核心实现逻辑

通过动态调整放大区域ImageBrush的Viewbox属性,根据鼠标在主图片上的位置截取对应区域,实现鼠标移动时放大图的同步更新。

XAML代码调整

  1. 为主图片容器添加鼠标移动事件,同时给放大区域的ImageBrush绑定Viewbox属性:
<!-- 主图片显示区域 -->
<Border CornerRadius="16" Margin="10" x:Name="uBottle_Image" Grid.Row="1" 
        MouseMove="uBottle_Image_MouseMove">
    <Border.Effect>
        <DropShadowEffect BlurRadius="10" Direction="10" Opacity="0.25" RenderingBias="Quality" ShadowDepth="0"/>
    </Border.Effect>
    <Border.Background>
        <ImageBrush x:Name="uImageControl_Brush" Stretch="Uniform" 
                    ImageSource="/Views/ImageView/LUCID_TRI071S-M_221100697__20240304180535053_image0.jpg" />
    </Border.Background>
</Border>

<!-- 放大图显示区域 -->
<Border CornerRadius="16" Margin="10" x:Name="uBottleZoom_Image" Grid.Row="1" >
    <Border.Effect>
        <DropShadowEffect BlurRadius="10" Direction="10" Opacity="0.25" RenderingBias="Quality" ShadowDepth="0"/>
    </Border.Effect>
    <Border.Background>
        <ImageBrush x:Name="uImageControlZoom_Brush" Stretch="UniformToFill" 
                    ImageSource="/Views/ImageView/LUCID_TRI071S-M_221100697__20240304180535053_image0.jpg"
                    Viewbox="{Binding ZoomViewbox}" ViewboxUnits="RelativeToBoundingBox"/>
    </Border.Background>
</Border>

后台代码实现(代码-behind模式)

// 放大倍数,可按需调整
private double _zoomFactor = 2.0;
public Rect ZoomViewbox { get; set; }

private void uBottle_Image_MouseMove(object sender, MouseEventArgs e)
{
    var border = sender as Border;
    if (border == null) return;

    // 获取鼠标在容器内的坐标
    Point mousePos = e.GetPosition(border);
    double borderWidth = border.ActualWidth;
    double borderHeight = border.ActualHeight;

    // 获取图片源的实际尺寸
    ImageBrush brush = border.Background as ImageBrush;
    if (brush?.ImageSource == null) return;

    double imgWidth = brush.ImageSource.Width;
    double imgHeight = brush.ImageSource.Height;

    // 计算图片在容器内的实际显示尺寸和偏移(适配Uniform拉伸)
    double scale = Math.Min(borderWidth / imgWidth, borderHeight / imgHeight);
    double displayImgWidth = imgWidth * scale;
    double displayImgHeight = imgHeight * scale;
    double offsetX = (borderWidth - displayImgWidth) / 2;
    double offsetY = (borderHeight - displayImgHeight) / 2;

    // 过滤鼠标在图片空白区域的情况
    if (mousePos.X < offsetX || mousePos.X > offsetX + displayImgWidth ||
        mousePos.Y < offsetY || mousePos.Y > offsetY + displayImgHeight)
    {
        return;
    }

    // 计算鼠标在原图上的相对比例
    double relativeX = (mousePos.X - offsetX) / displayImgWidth;
    double relativeY = (mousePos.Y - offsetY) / displayImgHeight;

    // 计算放大区域的Viewbox参数
    double viewboxSize = 1 / _zoomFactor;
    double viewboxX = Math.Max(0, relativeX - viewboxSize / 2);
    double viewboxY = Math.Max(0, relativeY - viewboxSize / 2);
    // 确保Viewbox不超出原图范围
    viewboxX = Math.Min(viewboxX, 1 - viewboxSize);
    viewboxY = Math.Min(viewboxY, 1 - viewboxSize);

    // 更新绑定属性
    ZoomViewbox = new Rect(viewboxX, viewboxY, viewboxSize, viewboxSize);
    OnPropertyChanged(nameof(ZoomViewbox));
}

// 实现INotifyPropertyChanged接口(窗口类需继承该接口)
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

关键注意点

  • 窗口类必须实现INotifyPropertyChanged接口,否则绑定属性更新无法同步到UI。
  • _zoomFactor值越大,放大倍数越高,可根据需求灵活调整。
  • 若采用MVVM模式,可将鼠标移动逻辑和属性迁移至ViewModel,通过绑定或命令完成交互。

内容的提问来源于stack exchange,提问作者abbas akbarzade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:34:53