在Panel控件中滚动GDI像素

时间:2015-10-09 04:07:02

标签: c# .net winforms gdi+

我们如何使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方法......但是我很难找到更多关于这些方法的信息。

2 个答案:

答案 0 :(得分:1)

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

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);
    }

}

答案 1 :(得分:1)

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

try{
    //Create a vertex
    Vertex ver1 = tx1.addVertexWithLabel("user");
    ver1.setProperty("PK",entityPK);
    ver1.setProperty("EntitySet",entitySet);
    for (Entry<String, ByteIterator> entry : values.entrySet()){
        //add properties
        ver1.setProperty(entry.getKey(), entry.getValue().toString());
    }
}

您可以通过关注e.ClipRectangle属性来进一步优化Paint事件处理程序,并在剪切项目时跳过绘制项目。以防万一:指定AutoScrollMinSize属性以适合项目。