C#UserControl滚动条问题

时间:2019-05-24 14:21:19

标签: c# winforms user-controls scrollbar

我在设置VerticalScroll/HorizontalScroll.Value属性时遇到麻烦。每次设置该值时,滚动条都会移动,然后回退(请参见下面的屏幕截图)

screenshot

这是我的用户控件的代码:

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

(控制视图当前无法移动-我已经使用了XY值,但是现在正在使用滚动条值)

我见过this问题,但是两次设置值或调用PerformLayout()似乎对我不起作用。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

根据我对代码的了解,您不需要任何自定义代码即可管理图形的滚动。

首先,您需要在用户控件内添加一个子面板,该子面板将成为图形的容器。因此,您可以将绘图代码移动到此面板。如果图纸需要更大,则必须确保此面板将调整自身大小。这将在用户控件上显示滚动条。

第二,必须将用户控件的AutoScroll属性设置为True。这样做将确保可以滚动任何大小或位置超过用户控件大小的子控件。也看看AutoScrollMargin属性。这是由框架自动完成的,因此不需要其他代码。不漂亮吗?

最后,您可以删除添加的两个滚动条。

编辑: 而且,在绘制时,您无需补偿滚动位置。您只用原点0,0绘制即可,而无需担心滚动。另外,这样做可以防止由于不断重绘而引起的闪烁。