Click here to Skip to main content
15,910,980 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:
C#
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


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.
Posted
Updated 24-Jul-17 19:57pm
Comments
Graeme_Grant 24-Jul-17 18:48pm    
have you tried using Google search? winform scrollable panel - Google Search[^]
Sicppy 24-Jul-17 22:53pm    
I already have a scrollable panel, I just can't get the item inside the panel longer than 1260
Graeme_Grant 25-Jul-17 0:41am    
I guess that you did not look at the link that I provided... Here is a StackOverflow answer that explains how to do what you want: https://stackoverflow.com/a/4306333 (from the search results of the Google search provided above).
BillWoodruff 24-Jul-17 22:33pm    
Is this a Windows Form application ? If it is, there's an easy way to achieve what you want.
Sicppy 24-Jul-17 22:52pm    
Yes it is a windows forms application.

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\nPanel Bounds: {pnl.Bounds}");
}
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.
 
Share this answer
 
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:
C#
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:
C#
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;
    }
}
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900