WinForm制作滑动框,实现滚动相册效果

WinForm制作滑动框,实现鼠标滚动查看效果

    界面层级:

 代码实现:

  public partial class Form1 : Form
    {
        // 初始时滑动面板所在高度Y
        private int initPanelY;

        // 鼠标松开时计算得到的滑动速度
        private double speed = 0;
        // 鼠标按下时得到的指针位置
        private int preCursorY = 0;
        // 鼠标按下的时间
        private DateTime pretime;
        //  鼠标松开的时间
        private DateTime curtime;
        // 上一次的鼠标位置
        private Point prePt;

        // tick间隔(0.02s一次) 
        private int interval = 20;
        // 剩余Tick次数
        private int remainTickTime = 0;

        public Form1()
        {
            InitializeComponent();

            initPanelY = ScrollPanel.Location.Y;
            this.vScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.ScrollBar_Scroll);
            ScrollPanel.MouseWheel += new MouseEventHandler(this.ScrollPanel_MouseWheel);
            ScrollPanel.MouseDown += new MouseEventHandler(this.ScrollPanel_MouseDown);
            ScrollPanel.MouseUp += new MouseEventHandler(this.ScrollPanel_MouseUp);
            ScrollPanel.MouseMove += new MouseEventHandler(this.ScrollPanel_MouseMove);

            InitTimer();
        }

        /// <summary>
        /// 鼠标按下滑动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ScrollPanel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int px = Cursor.Position.X - prePt.X;
                int py = Cursor.Position.Y - prePt.Y;
                ScrollPanel.Location = new Point(ScrollPanel.Location.X, ScrollPanel.Location.Y + py);
                prePt = Cursor.Position;

                ControlVerticalShowRegion();
            }
        }

        /// <summary>
        ///  将滑动面板控制在父面板显示区域内( Y方向)
        /// </summary>
        private void ControlVerticalShowRegion()
        {
            if (ScrollPanel.Height > BackPanel.Height)
            {
                // 滑到顶部,归位
                if (ScrollPanel.Location.Y > initPanelY)
                {
                    ScrollPanel.Location = new Point(ScrollPanel.Location.X, initPanelY);
                    timer1.Enabled = false;
                    timer1.Stop();
                }
                // 滑到底部了,归位(y减高差)
                if (initPanelY + BackPanel.Height > ScrollPanel.Location.Y + ScrollPanel.Height)
                {
                    ScrollPanel.Location = new Point(ScrollPanel.Location.X, initPanelY - (ScrollPanel.Height - BackPanel.Height));
                    timer1.Enabled = false;
                    timer1.Stop();
                }
                // 高差
                int heightDif = ScrollPanel.Height - BackPanel.Height;
                // panel 垂直滚动范围
                int value = -ScrollPanel.Location.Y;
                double diff = (double)vScrollBar.Maximum - (double)vScrollBar.LargeChange;
                double per = value / diff;
                double p = (double)value / (double)heightDif;
                // 更新滑动条
                vScrollBar.Value = (int)(p * 100);
            }
        }

        /// <summary>
        /// 鼠标悬浮滚动
        /// </summary>
        private void ScrollPanel_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // 滚动速度
            int scrollSpeed = 20;
            if (ScrollPanel.Height > BackPanel.Height)
            {
                ControlVerticalShowRegion();

                int delta = (e.Delta / Math.Abs(e.Delta)) * scrollSpeed;
                ScrollPanel.Location = new Point(ScrollPanel.Location.X, ScrollPanel.Location.Y + delta);
            }
        }

        /// <summary>
        /// 松开左键
        /// </summary>
        private void ScrollPanel_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                curtime = DateTime.Now;

                int curPanelY = Cursor.Position.Y;
                // 速度 = 距离 /  时间
                int dis = curPanelY - preCursorY;
                double seconds = (curtime - pretime).TotalMilliseconds;
                speed = (double)dis / seconds;
                // 持续时间
                double durTime = Math.Abs(speed);
                // 总tick次数 = 总共持续时间 durTime*1000 毫秒 / Tick间隔 interval=20
                // 总tick次数
                int tickTime = (int)((durTime * 1000) / interval);
                remainTickTime = tickTime;

                timer1.Interval = interval;
                timer1.Enabled = true;
                timer1.Start();
            }
        }

        /// <summary>
        /// 初始化计时器
        /// </summary>
        private void InitTimer()
        {
            timer1.Interval = interval;
            timer1.Tick += new EventHandler(Timer1_Tick);
        }

        private void Timer1_Tick(object sender, EventArgs e)
        {
            remainTickTime--;
            if (remainTickTime <= 0)
            {
                timer1.Enabled = false;
                timer1.Stop();
                return;
            }        
            // 根据拟合函数 得到y
            double deltaY = EasingCurve(remainTickTime, 0.001);
            int delta = (int)(speed > 0 ? deltaY : -deltaY);

            ScrollPanel.Location = new Point(ScrollPanel.Location.X, ScrollPanel.Location.Y + delta);
            ControlVerticalShowRegion();
        }

        // 拟合曲线 y = x ^ 2[0, durTime],在区间 [ 0, durTime ] 上均匀散列x,随x的等值递减y值加速递减
        /*
        *               |              /
        *               |             /
        *               |            /
        *               |          /
        *               |        /
        *               |     /   
        *               |  /          
        *               |__________________________________
        *             0     <—   tickTime (tick次数)                                                                              
        */
        /// <summary>
        /// 自定义缓动曲线  (本例使用二次函数,当然还有其他更好的拟合数学模型)
        /// </summary>
        private double EasingCurve(double x, double scaleFactor)
        {
            // y=x^2  二次函数
            return x * x * scaleFactor;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 开始加载Form时设置panel高度,可动态为其添加子元素
            ScrollPanel.Height = 800;
            // ...
        }

        /// <summary>
        /// 滚动条事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ScrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            if (ScrollPanel.Height > BackPanel.Height)
            {
                //  滑动条滚动
                int heightDif = ScrollPanel.Height - BackPanel.Height;
                double percent = (double)heightDif / (double)vScrollBar.Maximum;
                double percen = (double)heightDif / ((double)vScrollBar.Maximum - (double)vScrollBar.LargeChange);
                double value = (double)vScrollBar.Value * percen;

                int y = initPanelY - (int)value;
                ScrollPanel.Location = new Point(ScrollPanel.Location.X, y);
            }
        }

        /// <summary>
        /// 鼠标按下
        /// </summary>
        private void ScrollPanel_MouseDown(object sender, MouseEventArgs e)
        {
            prePt = Cursor.Position;
            preCursorY = Cursor.Position.Y;
            pretime = DateTime.Now;

            //timer1.Interval = 5000;
            timer1.Enabled = false;
            timer1.Stop();
        }

    }

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WinForm 是一种 Windows Forms 应用程序开发架,可以用于创建图形用户界面(GUI)。实现相册功能,我们可以使用 WinForm 提供的控件和功能来实现。 首先,我们可以创建一个主窗口,通过使用 WinForm 提供的布局控件(如 Panel、TableLayoutPanel 等),来布局相册的界面。可以选择以网格形式显示相册中的照片,也可以选择以列表或瀑布流形式展示。可以添加搜索栏、筛选器等功能来方便用户查找特定的照片。 接下来,我们可以使用 PictureBox 控件来显示照片。可以通过从本地文件夹或数据库中加载照片,并在相册界面中动态显示。用户可以通过点击照片来查看其详细信息或进行编辑。 除了显示照片,我们也可以添加一些交互功能。例如,用户可以通过拖拽操作来调整照片的排序或将其拖放到其他相册中。还可以通过双击照片放大,实现缩放功能。也可以添加一些操作按钮,如删除、分享、下载等,来对照片进行操作。 此外,为了增加用户体验,可以使用一些 WinForm 提供的动画效果来优化相册的界面。例如,在照片展示时可以添加过度动画,使界面更加流畅。 最后,为了提高相册的性能和稳定性,我们可以使用多线程、异步加载等技术来避免界面卡顿或崩溃。并且可以对相册进行数据的持久化存储,使用数据库或本地文件来保存用户的照片信息,以防止数据丢失。 总而言之,通过使用 WinForm,我们可以很方便地实现一个相册功能,包括照片的展示、交互功能的添加、界面的布局和优化等。 ### 回答2: WinForm是一种用于开发Windows桌面应用程序的技术,可以使用它来实现相册功能。 首先,我们可以设计一个用于展示图片的界面。可以使用PictureBox控件来显示图片,并为其设置适当的大小和布局。还可以添加导航按钮和滚动条用于浏览不同的图片。 然后,我们需要实现图片的加载功能。可以使用OpenFileDialog控件选择要加载的图片文件,并通过Image类将其加载到PictureBox控件中进行显示。 为了实现相册功能,可以在界面上添加一个列表控件,如ListBox或ListView,用于显示所有的图片文件。点击列表中的文件名,可以将对应的图片加载到PictureBox中进行显示。 另外,为了方便浏览图片,可以在界面上添加前进和后退按钮。点击前进按钮时,可以从列表中选择下一个图片进行加载;点击后退按钮时,可以选择上一个图片进行加载。 除了以上基本功能,还可以根据实际需求添加其他功能。例如,可以实现图片的缩放功能,让用户可以根据需要放大或缩小图片。还可以实现图片的删除功能,让用户可以删除不需要的图片。 最后,需要考虑图片文件的存储和管理。可以将图片文件存储在本地文件系统中的指定目录下,并将文件路径保存在程序的配置文件或数据库中,以便程序加载和管理。 总之,通过使用WinForm技术,我们可以轻松实现一个简单的相册应用程序,并添加各种附加功能以提升用户体验。 ### 回答3: WinForm 是一个用于开发 Windows 桌面应用程序的.NET 架。要实现相册功能,可以利用 WinForm 提供的控件和功能来完成。 首先,可以使用 PictureBox 控件来显示照片。通过调整控件的属性,可以使图片自动适应大小并居中显示。可以在窗体上放置多个 PictureBox 控件,每个控件对应一个照片。 其次,可以添加一个按钮或菜单,用于选择照片。点击按钮或菜单时,可以弹出文件选择对话,让用户选择要展示的照片。选择照片后,可以通过代码将选中的照片加载到对应的 PictureBox 控件中。 此外,可以添加导航按钮或滑动条,用于切换照片。用户可以通过点击按钮或拖动滑动条来切换当前显示的照片。可以使用代码控制 PictureBox 控件的显示,实现照片的切换效果。 另外,可以添加删除或编辑功能。当用户想删除或编辑某个照片时,可以添加相应的按钮或菜单,并编写相关的代码逻辑来处理用户的操作。例如,点击删除按钮时,可以弹出确认对话,确认后删除当前显示的照片。 最后,可以考虑添加图片缩放或旋转功能。通过对图片进行缩放或旋转,可以提供更好的用户体验。可以添加缩放或旋转按钮,并编写代码处理用户的操作。 通过以上的步骤和控件,我们可以利用 WinForm 实现一个简单的相册功能。用户可以选择照片,切换照片,删除或编辑照片,并对照片进行缩放或旋转操作。总体而言,WinForm 提供了丰富的控件和功能,可以快速实现相册的开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值