我在设置VerticalScroll/HorizontalScroll.Value
属性时遇到麻烦。每次设置该值时,滚动条都会移动,然后回退(请参见下面的屏幕截图)
这是我的用户控件的代码:
using System.Drawing;
using System.Windows.Forms;
namespace MyGanttChart
{
public class Chart : UserControl
{
public Chart()
{
HorizontalScroll.Visible = true;
VerticalScroll.Visible = true;
}
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
ScrollEventType scrollType = ScrollEventType.SmallIncrement;
if (e.Delta > 0)
scrollType = ScrollEventType.SmallDecrement;
ScrollOrientation orientation = ScrollOrientation.VerticalScroll;
if (ModifierKeys == Keys.Shift)
orientation = ScrollOrientation.HorizontalScroll;
ScrollEventArgs args = new ScrollEventArgs(scrollType, 1, orientation);
OnScroll(args);
}
protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
//if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement)
// X -= HorizontalScroll.LargeChange; // se.NewValue;
//else if (se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement)
// X += HorizontalScroll.LargeChange;
if ((se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement) &&
HorizontalScroll.Value + HorizontalScroll.LargeChange <= HorizontalScroll.Maximum)
{
HorizontalScroll.Value += HorizontalScroll.LargeChange;
}
else if ((se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement) &&
HorizontalScroll.Value - HorizontalScroll.LargeChange >= HorizontalScroll.Minimum)
{
HorizontalScroll.Value -= HorizontalScroll.LargeChange;
}
}
else if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
{
//if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement)
// Y -= VerticalScroll.LargeChange;
//else if (se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement)
// Y += VerticalScroll.LargeChange;
if ((se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement) &&
VerticalScroll.Value + VerticalScroll.LargeChange <= VerticalScroll.Maximum)
{
VerticalScroll.Value += VerticalScroll.LargeChange;
}
else if ((se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement) &&
VerticalScroll.Value - VerticalScroll.LargeChange >= VerticalScroll.Minimum)
{
VerticalScroll.Value -= VerticalScroll.LargeChange;
}
}
this.Invalidate(); //Force the control to redraw
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (!this.DesignMode)
Draw(e.Graphics, e.ClipRectangle);
}
public float X = 0;
public float Y = 0;
private void Draw(Graphics graphics, Rectangle rect)
{
graphics.TranslateTransform(X, Y);
graphics.Clear(Color.White);
Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
graphics.DrawString("hi", this.Font, new SolidBrush(Color.Black), center.X, center.Y, new StringFormat() { Alignment = StringAlignment.Center});
graphics.Flush();
}
}
}
(控制视图当前无法移动-我已经使用了X
和Y
值,但是现在正在使用滚动条值)
我见过this问题,但是两次设置值或调用PerformLayout()
似乎对我不起作用。有什么建议吗?
答案 0 :(得分:0)
根据我对代码的了解,您不需要任何自定义代码即可管理图形的滚动。
首先,您需要在用户控件内添加一个子面板,该子面板将成为图形的容器。因此,您可以将绘图代码移动到此面板。如果图纸需要更大,则必须确保此面板将调整自身大小。这将在用户控件上显示滚动条。
第二,必须将用户控件的AutoScroll属性设置为True。这样做将确保可以滚动任何大小或位置超过用户控件大小的子控件。也看看AutoScrollMargin属性。这是由框架自动完成的,因此不需要其他代码。不漂亮吗?
最后,您可以删除添加的两个滚动条。
编辑: 而且,在绘制时,您无需补偿滚动位置。您只用原点0,0绘制即可,而无需担心滚动。另外,这样做可以防止由于不断重绘而引起的闪烁。