WPF C#实现ImageBrush鼠标悬停时局部区域同步放大效果
WPF图片跟随鼠标同步放大实现方案
核心实现逻辑
通过动态调整放大区域ImageBrush的Viewbox属性,根据鼠标在主图片上的位置截取对应区域,实现鼠标移动时放大图的同步更新。
XAML代码调整
- 为主图片容器添加鼠标移动事件,同时给放大区域的
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
相关产品推荐
相关产品推荐

