原理

先获取鼠标在控件中的坐标,在获取其每一项相对于ItemsControl的坐标,然后计算每一项离当前鼠标的距离,在根据这个距离,对其每一项进行适当的缩放

实现

创建一个类,命名为FishEyeItemsControl

public class FishEyeItemsControl : ItemsControl

添加应用鱼眼效果方法(控制其控件的缩放)

private void ApplyFishEyeEffect(UIElement element, double strength, double additionalScale = 0.0)
{
// 将鱼眼效果应用于控件的正中心位置 // 获取控件的宽度和高度
double width = element.RenderSize.Width;
double height = element.RenderSize.Height; // 计算控件的正中心位置
double centerX = width / 2.0;
double centerY = height / 2.0; // 创建 ScaleTransform 对象并设置缩放中心为控件的正中心
ScaleTransform scaleTransform = new ScaleTransform();
scaleTransform.CenterX = centerX;
scaleTransform.CenterY = centerY; // 根据强度调整缩放比例
scaleTransform.ScaleX = strength + additionalScale;
scaleTransform.ScaleY = strength + additionalScale; // 将 ScaleTransform 应用于控件的 RenderTransform
element.RenderTransform = scaleTransform;
}

当鼠标移入到ItemsControl区域内时,计算其项距离鼠标距离,实现鱼眼效果

CalculateStrength方法可根据实际需求进行更改

protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Point mousePosition = e.GetPosition(this);
hoveredIndex = -1; for (int i = 0; i < Items.Count; i++)
{
UIElement element = ItemContainerGenerator.ContainerFromIndex(i) as UIElement; if (element != null)
{
Point itemPosition = element.TranslatePoint(new Point(element.RenderSize.Width / 2, element.RenderSize.Height / 2), this);
double distance = CalculateDistance(mousePosition, itemPosition);
double strength = CalculateStrength(distance); ApplyFishEyeEffect(element, strength, Scale); if (distance < element.RenderSize.Width)
{
hoveredIndex = i;
}
}
}
} private double CalculateDistance(Point p1, Point p2)
{
double dx = p1.X - p2.X;
double dy = p1.Y - p2.Y;
return Math.Sqrt(dx * dx + dy * dy);
} private double CalculateStrength(double distance)
{
// 根据距离计算变换的强度
var strength = 1.0;
strength = Math.Exp(-distance / 100);
return strength;
}

当鼠标离开ItemsControl时,进行效果还原

protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e); for (int i = 0; i < Items.Count; i++)
{
UIElement element = ItemContainerGenerator.ContainerFromIndex(i) as UIElement; if (element != null)
{
ApplyFishEyeEffect(element, 1.0);
}
}
hoveredIndex = -1;
}

添加背景色,如果未设置,当鼠标处于两个项之间的空间会触发OnMouseLeave

public FishEyeItemsControl()
{
this.Background = Brushes.Transparent;
}

属性

依赖属性Scale是为了在Xaml中动态修改其效果

private int hoveredIndex = -1;

#region DependencyProperty

public double Scale
{
get { return (double)GetValue(ScaleProperty); }
set { SetValue(ScaleProperty, value); }
} // Using a DependencyProperty as the backing store for Scale. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ScaleProperty =
DependencyProperty.Register("Scale", typeof(double), typeof(FishEyeItemsControl), new FrameworkPropertyMetadata(1.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); #endregion

Xaml

  <zWorkUi:FishEyeItemsControl
Width="800"
Height="600"
ItemsSource="{Binding TestList}">
<zWorkUi:FishEyeItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</zWorkUi:FishEyeItemsControl.ItemsPanel>
<zWorkUi:FishEyeItemsControl.ItemTemplate>
<DataTemplate>
<Border
Width="50"
Height="50"
Margin="20,20"
Background="Red" />
</DataTemplate>
</zWorkUi:FishEyeItemsControl.ItemTemplate>
</zWorkUi:FishEyeItemsControl>

效果

鼠标未进入区域时

效果1

效果2

鼠标进入区域,移到某一项上时

效果1

效果2

WPF自定义控件之ItemsControl鱼眼效果的更多相关文章

  1. WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

  2. WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...

  3. WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要针对WPF项目 ...

  4. WPF自定义控件与样式(15)-终结篇

    原文:WPF自定义控件与样式(15)-终结篇 系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与 ...

  5. 【转】WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要针对WPF项目 ...

  6. 【转】WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: DataGrid自定义样式: ListView自定义样式: 二.Dat ...

  7. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  8. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  9. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  10. WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

随机推荐

  1. iOS开发流程总结(新坑持续更新)

    [上线前流程] 将测试环境修改成正式环境 修改版本号,而且build version比version多一位,如version设置为1.0.1,那么build就设置成1.0.1.x:这么做的理由是,当你 ...

  2. Python加密操作 对称加密/非对称加密

    安装包: pycryptodome https://pycryptodome.readthedocs.io/en/latest/src/installation.html#compiling-in-l ...

  3. 构建3D虚拟世界,有哪些3D建模方式?

    "沉浸.3D世界.虚拟社交.虚拟购物",人们畅想通过AR/VR以及其他互联网技术,把现实世界的楼房街道.天气温度.人际关系等投射到虚拟世界,拥有一个网络分身. 但目前来看,要想实现 ...

  4. python重拾第十二天-MYSQL数据库

    本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql 1. 数据库介 ...

  5. ubuntu18 编译安装gccxml

    最近需要在ubuntu上安装gccxml,我的ubuntu版本是18. 使用sudo apt-get install gccxml提示找不到gccxml,最后使用了编译安装的方式安装gccxml. 1 ...

  6. 在Winform程序中增加隐藏的按键处理,用于处理一些特殊的界面显示或者系统初始化操作

    以前,我看到一个朋友在对一个系统做初始化的时候,通过一组魔幻般的按键,调出来一个隐藏的系统设置界面,这个界面在常规的菜单或者工具栏是看不到的,因为它是一个后台设置的关键界面,不公开,同时避免常规用户的 ...

  7. 全网最适合入门的面向对象编程教程:13 类和对象的Python实现-可视化阅读代码神器Sourcetrail的安装使用

    全网最适合入门的面向对象编程教程:13 类和对象的 Python 实现-可视化阅读代码神器 Sourcetrail 的安装使用 摘要: 本文主要介绍了可视化阅读代码神器Sourcetrail的安装与使 ...

  8. Apache Kyuubi 在B站大数据场景下的应用实践

    01 背景介绍 近几年随着B站业务高速发展,数据量不断增加,离线计算集群规模从最初的两百台发展到目前近万台,从单机房发展到多机房架构.在离线计算引擎上目前我们主要使用Spark.Presto.Hive ...

  9. ping和tcping的区别

    ping是简单的测试网络连接情况的小命令,但是ping无法直接ping端口.某些网站还防ping,tcping工具也是通过ping来测试但是他能看端口是否打开

  10. CCF 命令行选项

    题目原文 问题描述(题目链接登陆账号有问题,要从这个链接登陆,然后点击"模拟考试",进去找本题目)   试题编号: 201403-3 试题名称: 命令行选项 时间限制: 1.0s ...