如何在可滚动面板中扩展控制超过屏幕大小 [英] How to expand control past screen size in scrollable panel

查看:81
本文介绍了如何在可滚动面板中扩展控制超过屏幕大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一种事件时间轴,将我的游戏中的事件与音乐同步,我尝试制作一个自定义时间轴控件并将其放入面板中,以便我可以滚动它,但我可以' t扩展控件超过限制。



我做了一些研究,发现你无法调整超出显示器宽度的表单对象的大小。这有什么解决方法吗?我已经将它放在带有自动滚动的面板中。



代码不太相关,但现在是:

I'm trying to create a sort of event timeline, to sync up events in my game with music, I tried making a custom timeline control and putting it inside of a panel so I could scroll through it, however I can't expand the control past a limit.

I did a little bit of research and found that you aren't able to resize form object beyond the width of your monitor. Is there any workaround for this? I already have it inside of a panel with autoscroll.

The code isn't too relevant but here it is:

public List<List<bool>> matrix = new List<List<bool>>();

public void ExpandWindow()
{
	Size mySize = new Size(matrix.Count * CellWidth, matrix[0].Count * RowHeight);
	MaximumSize = mySize;
	this.Size = mySize;
	Invalidate();
	MessageBox.Show("Timeline Width: " + matrix.Count + "\r\nLogical Width: " + (mySize.Width / CellWidth) + "\r\nPhysical Width: " + (Width / CellWidth));
}





调试消息框的输出是



The output of the debug messagebox is

Timeline Width: 4615
Logical Width: 4615
Physical Width: 1260





时间轴宽度为矩阵宽度,逻辑宽度是计算输出,物理宽度是实际设置的长度。



矩阵填充在代码中的其他地方/>


我尝试了什么:



我尝试重写SetBoundsCore函数,但是这最终阻止了控件的大小调整。



the timeline width is the matrix width, the logical width is what the calculation output, and the physical width is how long it actually got set to.

The matrix is populated elsewhere in the code

What I have tried:

I tried overriding the SetBoundsCore function, but that just ended up preventing the control from resizing at all.

推荐答案

我认为这里肯定有一些简单的东西。



虽然Win Form的绝对标称大小可能有限制,但使用滚动可以实现几乎无限的虚拟表面。例如:
I think there must be something simple you are missing here.

While there may be a limit to the absolute nominal size of a Win Form, you can have a virtually unlimited virtual surface by using scrolling. An example:
private void Form1_Load(object sender, EventArgs e)
{
    Panel pnl = new Panel();

    pnl.AutoSize = false;
    pnl.Dock = DockStyle.None;
    pnl.Anchor = AnchorStyles.None;
    
    pnl.AutoScroll = true;
       
    pnl.Size = new Size(10000, this.Height);

    pnl.BackColor = Color.AliceBlue;

    this.Controls.Add(pnl);

    pnl.Left = 0;
    pnl.Top = 0;

    Console.Write(


Form Bounds:{this.Bounds} \r\\\
Panel Bounds:{pnl.Bounds});
}
"Form Bounds: {this.Bounds}\r\nPanel Bounds: {pnl.Bounds}"); }

运行此控制台后输出到控制台:



表格边界:{X = 336,Y = 336,宽度= 1274,身高= 1527}

面板界限:{X = 0,Y = 0,宽度= 10000,身高= 1527}



如果此示例对您没有帮助,请告诉我。

The output to the Console after running this:

Form Bounds: {X=336,Y=336,Width=1274,Height=1527}
Panel Bounds: {X=0,Y=0,Width=10000,Height=1527}

Let me know if this example doesn't help you.


解决方案1的问题是内存消耗。您最好只虚拟化并渲染用户将看到的部分。这将大大提高整体性能并大幅减少内存使用量。这样你的面板可以超过100万像素宽!



这是一个例子。它有一个PictureBox和一个水平滚动条。



设计师:

The problem with solution 1 is the memory consumption. You are better of virtualizing and rendering only the part that the user will see. This will greatly improve overall performance and dramatically reduce memory usage. This way your panel can be over 1 million pixels wide!

Here is an example. It has one PictureBox and one horizontal Scrollbar.

Designer:
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
    this.pictureBox1 = new System.Windows.Forms.PictureBox();
    this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
    ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
    this.SuspendLayout();
    // 
    // pictureBox1
    // 
    this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
    | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right)));
    this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
    this.pictureBox1.Location = new System.Drawing.Point(13, 13);
    this.pictureBox1.Name = "pictureBox1";
    this.pictureBox1.Size = new System.Drawing.Size(259, 216);
    this.pictureBox1.TabIndex = 0;
    this.pictureBox1.TabStop = false;
    this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBox1_Paint);
    this.pictureBox1.Resize += new System.EventHandler(this.PictureBox1_Resize);
    // 
    // hScrollBar1
    // 
    this.hScrollBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right)));
    this.hScrollBar1.Location = new System.Drawing.Point(13, 232);
    this.hScrollBar1.Maximum = 5000;
    this.hScrollBar1.Name = "hScrollBar1";
    this.hScrollBar1.Size = new System.Drawing.Size(259, 20);
    this.hScrollBar1.TabIndex = 1;
    this.hScrollBar1.ValueChanged += new System.EventHandler(this.HScrollBar1_ValueChanged);
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.BackColor = System.Drawing.Color.White;
    this.ClientSize = new System.Drawing.Size(284, 261);
    this.Controls.Add(this.hScrollBar1);
    this.Controls.Add(this.pictureBox1);
    this.Name = "Form1";
    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
    this.Text = "Form1";
    ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
    this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.HScrollBar hScrollBar1;
}



代码隐藏:


Code-Behind:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        canvasWidth = 1000000 * (elementWidth + elementGap);
        CalcSize();
    }

    private readonly int elementWidth = 60;
    private readonly int elementGap = 10;

    private readonly Font font = new Font("Arial", 14);

    private int displayWidth;

    private int canvasWidth;
    private int offset = -1;

    private void PictureBox1_Paint(object sender, PaintEventArgs e)
    {
        // nothing to do!
        if (offset == hScrollBar1.Value) return;
        offset = hScrollBar1.Value;

        var gr = e.Graphics;

        // Set text rendering mode
        gr.TextRenderingHint = TextRenderingHint.AntiAlias;

        // Calculate cell positioning
        var step = elementWidth + elementGap;
        var count = (hScrollBar1.Value / step) + 1;

        using (var br = new SolidBrush(Color.Red))
        {
            for (int i = 0; i < displayWidth; i += step)
            {
                gr.DrawString(count.ToString(), font, br, i, 50);
                count++;
            }
        }
    }

    private void HScrollBar1_ValueChanged(object sender, EventArgs e)
    {
        pictureBox1.Invalidate();
    }

    private void PictureBox1_Resize(object sender, EventArgs e)
    {
        CalcSize();
    }

    private void CalcSize()
    {
        displayWidth = pictureBox1.Width;

        var max = canvasWidth - pictureBox1.Width;
        hScrollBar1.Maximum = max;
        if (hScrollBar1.Value > max) hScrollBar1.Value = max;

        hScrollBar1.LargeChange = displayWidth;
        hScrollBar1.SmallChange = elementWidth + elementGap;
    }
}


这篇关于如何在可滚动面板中扩展控制超过屏幕大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆