自定义控制和滚动,有帮助吗?

发布于 2024-08-22 12:52:32 字数 3371 浏览 4 评论 0原文

我无法在自定义控件中滚动。目前,它绘制了自己的内容(目前只是网格),并且应该被视为有很大的工作区域。但是,我无法滚动工作。

启用自动滚动后,我无法将其从工作区域的中心开始。

关闭自动滚动后,无论是在代码中设置滚动条还是实际滚动,我都无法让滚动条的值保持不变。

最重要的是,当使用单独的 HScroll 和 VScroll 控件时,根本不显示滚动条。

代码的当前状态正在尝试关闭 AutoScroll,但我承认在没有帮助的情况下我无法让它执行我想要的操作。

所以请帮忙!

这是到目前为止的代码:

public partial class TwoDimensionViewport : ScrollableControl
{
    private readonly Point MinOffset = new Point(-4000000, -4000000);
    private readonly Point MaxOffset = new Point(4000000, 4000000);

    private Point viewOffset;

    public TwoDimensionViewport()
    {
        InitializeComponent();
        DoubleBuffered = true;
        GridSize = 16;
        AutoScroll = false;            
        AdjustFormScrollbars(true);
    }

    protected override void AdjustFormScrollbars(bool displayScrollbars)
    {            
        VerticalScroll.Minimum = 0;
        VerticalScroll.Maximum = 8000000;
        HorizontalScroll.Minimum = 0;
        HorizontalScroll.Maximum = 8000000;
        HorizontalScroll.Enabled = true;
        VerticalScroll.Enabled = true;            
        HorizontalScroll.Visible = true;
        VerticalScroll.Visible = true;

        HorizontalScroll.Value = viewOffset.X + 4000000;
        VerticalScroll.Value = viewOffset.Y + 4000000;            
    }        

    private ViewSettingsProvider viewSettingsProvider;
    public ViewSettingsProvider ViewSettingsProvider
    {
        get
        {
            return viewSettingsProvider;
        }
        set
        {
            UnbindViewSettingsProvider();
            viewSettingsProvider = value;
            BindViewSettingsProvider();
        }
    }

    public int GridSize { get; private set; }

    protected override void OnScroll(ScrollEventArgs se)
    {
        base.OnScroll(se);

        if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll)
        {
            viewOffset.X = se.NewValue - 4000000;                
        }
        else if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
        {
            viewOffset.Y = se.NewValue - 4000000;
        }                        

        Invalidate();                        
    }

    protected override void OnPaint(PaintEventArgs pe)
    {            
        pe.Graphics.FillRectangle(Brushes.Black, pe.ClipRectangle);

        DrawGrid(pe.Graphics);            

        base.OnPaint(pe);
    }

    private void DrawGrid(Graphics graphics)
    {
        for (int i = 0, count = 0; i < ClientRectangle.Width; i++)
        {
            bool increaseCount = false;

            if ((i - viewOffset.X) % GridSize == 0)
            {
                graphics.DrawLine(
                    count % 5 == 0 ? Pens.White : Pens.DarkGray,
                    i, 0,
                    i, ClientRectangle.Height);

                increaseCount = true;
            }

            if ((i - viewOffset.Y) % GridSize == 0)
            {
                graphics.DrawLine(
                    count % 5 == 0 ? Pens.White : Pens.DarkGray,
                    0, i,
                    ClientRectangle.Width, i);

                increaseCount = true;
            }

            if (increaseCount)
                count++;
        }
    }

    private void BindViewSettingsProvider()
    {

    }

    private void UnbindViewSettingsProvider()
    {

    }
}

I can't get scrolling working in my custom control. Currently it draws it's own content (at the moment just grid) and should be treated as having a large area to work in. However, I can't get scrolling to work.

With AutoScroll on, I can't get it to start of at the center of the workable area.

With AutoScroll off, I can't get the values of the scrollbars to stick whether I set them in code or you actually scroll.

To top it all off, when using individual HScroll and VScroll controls no scrollbars show at all.

The current state the code is trying with AutoScroll off, but I'm at the point where I concede I can't make it do what I want without help.

So please help!

Here's the code so far:

public partial class TwoDimensionViewport : ScrollableControl
{
    private readonly Point MinOffset = new Point(-4000000, -4000000);
    private readonly Point MaxOffset = new Point(4000000, 4000000);

    private Point viewOffset;

    public TwoDimensionViewport()
    {
        InitializeComponent();
        DoubleBuffered = true;
        GridSize = 16;
        AutoScroll = false;            
        AdjustFormScrollbars(true);
    }

    protected override void AdjustFormScrollbars(bool displayScrollbars)
    {            
        VerticalScroll.Minimum = 0;
        VerticalScroll.Maximum = 8000000;
        HorizontalScroll.Minimum = 0;
        HorizontalScroll.Maximum = 8000000;
        HorizontalScroll.Enabled = true;
        VerticalScroll.Enabled = true;            
        HorizontalScroll.Visible = true;
        VerticalScroll.Visible = true;

        HorizontalScroll.Value = viewOffset.X + 4000000;
        VerticalScroll.Value = viewOffset.Y + 4000000;            
    }        

    private ViewSettingsProvider viewSettingsProvider;
    public ViewSettingsProvider ViewSettingsProvider
    {
        get
        {
            return viewSettingsProvider;
        }
        set
        {
            UnbindViewSettingsProvider();
            viewSettingsProvider = value;
            BindViewSettingsProvider();
        }
    }

    public int GridSize { get; private set; }

    protected override void OnScroll(ScrollEventArgs se)
    {
        base.OnScroll(se);

        if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll)
        {
            viewOffset.X = se.NewValue - 4000000;                
        }
        else if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
        {
            viewOffset.Y = se.NewValue - 4000000;
        }                        

        Invalidate();                        
    }

    protected override void OnPaint(PaintEventArgs pe)
    {            
        pe.Graphics.FillRectangle(Brushes.Black, pe.ClipRectangle);

        DrawGrid(pe.Graphics);            

        base.OnPaint(pe);
    }

    private void DrawGrid(Graphics graphics)
    {
        for (int i = 0, count = 0; i < ClientRectangle.Width; i++)
        {
            bool increaseCount = false;

            if ((i - viewOffset.X) % GridSize == 0)
            {
                graphics.DrawLine(
                    count % 5 == 0 ? Pens.White : Pens.DarkGray,
                    i, 0,
                    i, ClientRectangle.Height);

                increaseCount = true;
            }

            if ((i - viewOffset.Y) % GridSize == 0)
            {
                graphics.DrawLine(
                    count % 5 == 0 ? Pens.White : Pens.DarkGray,
                    0, i,
                    ClientRectangle.Width, i);

                increaseCount = true;
            }

            if (increaseCount)
                count++;
        }
    }

    private void BindViewSettingsProvider()
    {

    }

    private void UnbindViewSettingsProvider()
    {

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

潜移默化 2024-08-29 12:52:32

是的,这看起来很麻烦。相反,从面板派生您的类。将其 AutoScroll 设置为 true,将 AutoMinSize 属性设置为可滚动网格的大小。这会自动使滚动条出现。使用OnPaintBackground()方法绘制背景和网格。您需要通过 AutoScrollPosition 属性来偏移网格的绘制:

  protected override void OnPaintBackground(PaintEventArgs e) {
    e.Graphics.FillRectangle(Brushes.Black, this.ClientRectangle);
    e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
    for (int x = 0; x < this.AutoScrollMinSize.Width; x += GridSize) 
      e.Graphics.DrawLine(Pens.White, x, 0, x, this.AutoScrollMinSize.Height);
    for (int y = 0; y < this.AutoScrollMinSize.Height; y += GridSize)
      e.Graphics.DrawLine(Pens.White, 0, y, this.AutoScrollMinSize.Width, y);
  }

Yeah, that looks like trouble. Derive your class from Panel instead. Set its AutoScroll to true, AutoMinSize property to the size of the scrollable grid. That automatically makes the scrollbars appear. Use the OnPaintBackground() method to draw the background and grid. You'll need to offset the drawing of the grid by the AutoScrollPosition property:

  protected override void OnPaintBackground(PaintEventArgs e) {
    e.Graphics.FillRectangle(Brushes.Black, this.ClientRectangle);
    e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
    for (int x = 0; x < this.AutoScrollMinSize.Width; x += GridSize) 
      e.Graphics.DrawLine(Pens.White, x, 0, x, this.AutoScrollMinSize.Height);
    for (int y = 0; y < this.AutoScrollMinSize.Height; y += GridSize)
      e.Graphics.DrawLine(Pens.White, 0, y, this.AutoScrollMinSize.Width, y);
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文