弄了一个自定义控件,主要是两个TableLayoutPanel,一个作为表头使用,一个作为列表。要求垂直滚动条滚动时表头不动(这也是为什么用两个TableLayoutPanel的原因),水平滚动时,两个TableLayoutPanel一起滚动。
为此添加了一个VScrollBar和一个HScrollBar。但是不知道如何控制两个TableLayoutPlanel。如果单纯改变控件的loacation,界面闪烁的很厉害(控件比较多)。请问有什么办法吗?最好能有实例学习一下,谢谢。
为此添加了一个VScrollBar和一个HScrollBar。但是不知道如何控制两个TableLayoutPlanel。如果单纯改变控件的loacation,界面闪烁的很厉害(控件比较多)。请问有什么办法吗?最好能有实例学习一下,谢谢。
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace Scrollbar
{
public class Form1 : Form
{
private OpenFileDialog openFileDialog1;
private PictureBox pictureBox1;
private VScrollBar vScrollBar1;
private HScrollBar hScrollBar1;
public Form1()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.openFileDialog1 = new OpenFileDialog();
this.pictureBox1 = new PictureBox();
this.vScrollBar1 = new VScrollBar();
this.hScrollBar1 = new HScrollBar();
this.pictureBox1.SuspendLayout();
this.SuspendLayout();
this.pictureBox1.BorderStyle = BorderStyle.FixedSingle;
this.pictureBox1.Controls.AddRange(
new Control[] { this.vScrollBar1, this.hScrollBar1});
this.pictureBox1.Dock = DockStyle.Fill;
this.pictureBox1.Size = new System.Drawing.Size(440, 349);
this.pictureBox1.DoubleClick += new EventHandler(this.pictureBox1_DoubleClick); this.vScrollBar1.Dock = DockStyle.Right;
this.vScrollBar1.Location = new System.Drawing.Point(422, 0);
this.vScrollBar1.Size = new System.Drawing.Size(16, 331);
this.vScrollBar1.Visible = false;
this.vScrollBar1.Scroll +=
new ScrollEventHandler(this.HandleScroll);
this.hScrollBar1.Dock = DockStyle.Bottom;
this.hScrollBar1.Location = new System.Drawing.Point(0, 331);
this.hScrollBar1.Size = new System.Drawing.Size(438, 16);
this.hScrollBar1.Visible = false;
this.hScrollBar1.Scroll +=
new ScrollEventHandler(this.HandleScroll);
this.ClientSize = new System.Drawing.Size(440, 349);
this.Controls.AddRange(new Control[] {this.pictureBox1});
this.Text = "Form1";
this.Resize += new System.EventHandler(this.Form1_Resize);
this.pictureBox1.ResumeLayout(false);
this.ResumeLayout(false); } [STAThread]
static void Main()
{
Application.Run(new Form1());
}private void pictureBox1_DoubleClick (Object sender, EventArgs e)
{
// Open the dialog box so the user can select a new image.
if(openFileDialog1.ShowDialog() != DialogResult.Cancel)
{
// Display the image in the PictureBox.
pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
this.DisplayScrollBars();
this.SetScrollBarValues();
}
}
private void Form1_Resize (Object sender, EventArgs e)
{
// If the PictureBox has an image, see if it needs
// scrollbars and refresh the image.
if(pictureBox1.Image != null)
{
this.DisplayScrollBars();
this.SetScrollBarValues();
this.Refresh();
}
}
public void DisplayScrollBars()
{
// If the image is wider than the PictureBox, show the HScrollBar.
if (pictureBox1.Width > pictureBox1.Image.Width - this.vScrollBar1.Width)
{
hScrollBar1.Visible = false;
}
else
{
hScrollBar1.Visible = true;
}
// If the image is taller than the PictureBox, show the VScrollBar.
if (pictureBox1.Height >
pictureBox1.Image.Height - this.hScrollBar1.Height)
{
vScrollBar1.Visible = false;
}
else
{
vScrollBar1.Visible = true;
}
}
private void HandleScroll(Object sender, ScrollEventArgs se)
{
/* Create a graphics object and draw a portion
of the image in the PictureBox. */
Graphics g = pictureBox1.CreateGraphics();
g.DrawImage(pictureBox1.Image,
new Rectangle(0, 0, pictureBox1.Right - vScrollBar1.Width,
pictureBox1.Bottom - hScrollBar1.Height),
new Rectangle(hScrollBar1.Value, vScrollBar1.Value,
pictureBox1.Right - vScrollBar1.Width,
pictureBox1.Bottom - hScrollBar1.Height),
GraphicsUnit.Pixel); pictureBox1.Update();
}public void SetScrollBarValues()
{
// Set the Maximum, Minimum, LargeChange and SmallChange properties.
this.vScrollBar1.Minimum = 0;
this.hScrollBar1.Minimum = 0; // If the offset does not make the Maximum less than zero, set its value.
if( (this.pictureBox1.Image.Size.Width - pictureBox1.ClientSize.Width) > 0)
{
this.hScrollBar1.Maximum =
this.pictureBox1.Image.Size.Width - pictureBox1.ClientSize.Width;
}
// If the VScrollBar is visible, adjust the Maximum of the
// HSCrollBar to account for the width of the VScrollBar.
if(this.vScrollBar1.Visible)
{
this.hScrollBar1.Maximum += this.vScrollBar1.Width;
}
this.hScrollBar1.LargeChange = this.hScrollBar1.Maximum / 10;
this.hScrollBar1.SmallChange = this.hScrollBar1.Maximum / 20; // Adjust the Maximum value to make the raw Maximum value
// attainable by user interaction.
this.hScrollBar1.Maximum += this.hScrollBar1.LargeChange;
// If the offset does not make the Maximum less than zero, set its value.
if( (this.pictureBox1.Image.Size.Height - pictureBox1.ClientSize.Height) > 0)
{
this.vScrollBar1.Maximum =
this.pictureBox1.Image.Size.Height - pictureBox1.ClientSize.Height;
} // If the HScrollBar is visible, adjust the Maximum of the
// VSCrollBar to account for the width of the HScrollBar.
if(this.hScrollBar1.Visible)
{
this.vScrollBar1.Maximum += this.hScrollBar1.Height;
}
this.vScrollBar1.LargeChange = this.vScrollBar1.Maximum / 10;
this.vScrollBar1.SmallChange = this.vScrollBar1.Maximum / 20;
// Adjust the Maximum value to make the raw Maximum value
// attainable by user interaction.
this.vScrollBar1.Maximum += this.vScrollBar1.LargeChange;
} }
}
this.SuspendLayout(); // 动前挂起布局
...
this.ResumeLayout(true); 动完恢复布局
后来经一位高人指点终于解决了这个问题,拿出来跟大家分享一下。这个办法一下解决了闪烁和同步滚动两个问题。其实过程挺简单的,原因不知道谁能解释一下。将要作为内容显示的TableLayOutPanel放入一个Panel,然后VScrollbar也放入这个Panel。然后Panel设为FILL,而TableLayOutPanel不能设为FIll(一旦Fill了肯定闪烁)。然后用VScrollbar操作TableLayOutPanel的滚动,就是LOCATION就能解决这两个问题。其实关键是TableLayOutPanel不能设为FILL,跟那个Panel没什么关系,这就需要我们根据内容计算出TableLayOutPanel的高度,并且还要考虑窗口最大化后TableLayOutPanel自动适应的问题。