在面板控件中滚动 GDI 像素
Scrolling GDI pixels in Panel control
我们如何使面板控件滚动其中的内容?我不是在谈论控件或用户控件或自定义控件。我说的只是像素;用 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();
}
}
}
上面的代码绘制了一个蓝色矩形(有点像垂直列表)。当矩形的数量延伸到面板的高度时,我希望面板滚动。
我一直无法找到如何执行此操作,因为大多数结果仅 return 与滚动自定义控件相关的内容。
我确实在某处(我找不到了)读到您可以使用一些 translateX 或 translateY 方法...但我很难找到更多关于这些方法的信息。
这是一个关于如何手动显示滚动条的粗略示例。该面板包含一个可以单击和拖动的红色矩形。如果将矩形移出可视区域,则会出现滚动条。
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);
}
}
你的代码中有一个简单的错误,你忘记了用滚动量来抵消你绘制的内容。 Panel class 还有另外两个怪癖,它被优化为一个容器控件并在它绘制的方式上偷工减料。您可以通过从 Panel 创建派生的 class 来摆脱所有这三个问题。项目 > 添加 Class > 粘贴如下所示的代码。构建 > 构建并将新控件从工具箱顶部拖放到您的窗体上。
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 属性 以适合项目。
我们如何使面板控件滚动其中的内容?我不是在谈论控件或用户控件或自定义控件。我说的只是像素;用 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();
}
}
}
上面的代码绘制了一个蓝色矩形(有点像垂直列表)。当矩形的数量延伸到面板的高度时,我希望面板滚动。
我一直无法找到如何执行此操作,因为大多数结果仅 return 与滚动自定义控件相关的内容。
我确实在某处(我找不到了)读到您可以使用一些 translateX 或 translateY 方法...但我很难找到更多关于这些方法的信息。
这是一个关于如何手动显示滚动条的粗略示例。该面板包含一个可以单击和拖动的红色矩形。如果将矩形移出可视区域,则会出现滚动条。
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);
}
}
你的代码中有一个简单的错误,你忘记了用滚动量来抵消你绘制的内容。 Panel class 还有另外两个怪癖,它被优化为一个容器控件并在它绘制的方式上偷工减料。您可以通过从 Panel 创建派生的 class 来摆脱所有这三个问题。项目 > 添加 Class > 粘贴如下所示的代码。构建 > 构建并将新控件从工具箱顶部拖放到您的窗体上。
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 属性 以适合项目。