【问题标题】:Scrolling GDI pixels in Panel control在面板控件中滚动 GDI 像素
【发布时间】:2016-01-06 21:34:47
【问题描述】:

我们如何让 Panel 控件滚动其中的任何内容?我不是在谈论控件、用户控件或自定义控件。我说的只是像素;用 GDI+ 绘制:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GDITEST
{
    public partial class Form1 : Form
    {
        public class Item
        {
            public int Height { get; set; }
            public int Width { get; set; }
            public int Top { get; set; }
        }

        internal List<Item> items = new List<Item>();

        public Form1()
        {
            InitializeComponent();
        }

        private void panel_Paint(object sender, PaintEventArgs e)
        {
            if (items != null)
            {
                if (items.Count >= 1)
                {
                    foreach (Item item in items)
                    {
                        using (Pen pen = new Pen(Color.Blue, 1))
                        {
                            int count;
                            count = items.Count;

                            count = count >= 1 ? count : 1;
                            e.Graphics.DrawRectangle(pen, 0, item.Top, (item.Width - SystemInformation.VerticalScrollBarWidth), item.Height);
                        }
                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            items.Add(new Item() { Width = this.Width, Height = 25, Top = (items.Count * 25) });
            panel.Refresh();
        }
    }
}

上面的代码绘制了一个蓝色矩形(有点像垂直列表)。当矩形的数量扩展面板的高度时,我希望面板滚动。

我无法找到如何执行此操作,因为大多数结果只返回与滚动自定义控件相关的内容。

我确实在某个地方(我再也找不到)读到您可以使用一些 translateX 或 translateY 方法......但是我很难找到更多关于这些方法的信息。

【问题讨论】:

    标签: c# .net winforms gdi+


    【解决方案1】:

    您的代码中有一个简单的错误,您忘记用滚动量来抵消您绘制的内容。 Panel 类还有另外两个怪癖,它被优化为一个容器控件,并在它的绘制方式上偷工减料。通过从 Panel 创建派生类,您可以摆脱所有三个问题。项目 > 添加类 > 粘贴如下所示的代码。 Build > Build 并将新控件从工具箱顶部拖放到表单上。

    using System;
    using System.Windows.Forms;
    
    class MyPanel : Panel {
        public MyPanel() {
            this.DoubleBuffered = this.ResizeRedraw = true;
        }
        protected override void OnPaint(PaintEventArgs e) {
            e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
            base.OnPaint(e);
        }
    }
    

    您可以通过注意 e.ClipRectangle 属性来进一步优化您的 Paint 事件处理程序,并在项目被剪辑时跳过它的绘制。以防万一:分配 AutoScrollMinSize 属性以适应项目。

    【讨论】:

    • 这实际上并没有用,但它确实给了我更多信息来进行更多搜索(TranslateTransform),我最终在这个网站上找到了另一个有效的答案。我也错过了 this.AutoScrollMinSize = new Size(this.Width, this.Height + 1);谢谢@汉斯。 :)
    【解决方案2】:

    这是一个关于如何手动显示滚动条的粗略示例。该面板包含一个红色矩形,可以单击和拖动。如果将矩形移到可视区域之外,则会出现滚动条。

    public class DrawPanel : Panel {
    
        public Rectangle rect = new Rectangle(0, 0, 200, 100);
        int offsetX = 0;
        int offsetY = 0;
        bool grabbing = false;
    
        public DrawPanel() {
            Dock = DockStyle.Fill;
            AutoScroll = true;
        }
    
        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e);
            var p = e.Location;
            if (rect.Contains(p)) {
                grabbing = true;
                offsetX = rect.X - p.X;
                offsetY = rect.Y - p.Y;
            }
        }
    
        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            grabbing = false;
        }
    
        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e);
            if (grabbing) {
                var p = e.Location;
                rect.Location = new Point(p.X + offsetX, p.Y + offsetY);
                Invalidate();
    
                int right = rect.X + rect.Width;
                int bottom = rect.Y + rect.Height;
    
                if (right > Width || bottom > Height) {
                    this.AutoScrollMinSize = new Size(right + 1, bottom + 1);
                }
            }
        }
    
        protected override void OnScroll(ScrollEventArgs se) {
            base.OnScroll(se);
            Invalidate();
        }
    
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
    
            var g = e.Graphics;
            var p = AutoScrollPosition;
            Rectangle r = rect;
            r.X += p.X;
            r.Y += p.Y;
            g.DrawRectangle(Pens.Red, r);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-27
      • 2018-12-24
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多