简体   繁体   English

Windows窗体中的Panel和ScrollBar

[英]Panel and ScrollBar in Windows forms

I am using a panel to display a image in windows forms I am drawing image in the panel in Panel_Paint event as follows: 我正在使用面板在Windows窗体中显示图像我正在Panel_Paint事件中在面板中绘制图像,如下所示:

Graphics g = panel1.CreateGraphics();
Image im = new Bitmap(@"../../Data/#3_Page2.PNG");
g.DrawImage(im,new Point(10,10));

Now, the image is drawn as i expected, with some part of the bottom of the image not displaying as its height is greater than forms height. 现在,按照我的预期绘制图像,图像底部的某些部分不显示,因为其高度大于窗体的高度。 I have added the VScrollBar now. 我现在添加了VScrollBar。 How do i make that panel to view the rest of the image with the help of VScrollBar. 我如何使该面板在VScrollBar的帮助下查看其余图像。

You can use PictureBox with SizeMode set to AutoSize and AutoScroll property of Panel. 您可以使用将SizeMode设置为Panel的AutoSize和AutoScroll属性的PictureBox。 That way the panel should add scrollbars if they are needed. 这样,面板可以在需要时添加滚动条。

PictureBox pictureBox = new System.Windows.Forms.PictureBox();
pictureBox.Image = new Bitmap(@"../../Data/#3_Page2.PNG");
pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;

panel.AutoScroll = true;
panel.Controls.Add(this.pictureBox);

This solution works, however if your image is large enough, there is a little flicker when you scroll (however it's acceptable). 此解决方案有效,但是,如果您的图像足够大,则滚动时会出现一点闪烁(但是可以接受)。 First you have to add a VScrollBar right on the right of your panel and a HScrollBar right under the bottom of your panel. 首先,您必须在面板右侧添加一个VScrollBar ,并在面板底部下方添加一个HScrollBar This demo requires you have a VScrollBar named vScrollBar1 and HScrollBar named hScrollBar1 , a Button named buttonOpenImage to allow user to open some image, a Panel named panel1 used as the main area to draw the image: 该演示需要你有一个VScrollBar名为vScrollBar1HScrollBar命名hScrollBar1 ,一个Button名为buttonOpenImage允许用户打开一些图像,一个Panel命名panel1作为主要区域绘制图像:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();            
        //To prevent/eliminate flicker, do this
        typeof(Panel).GetProperty("DoubleBuffered", 
                                  System.Reflection.BindingFlags.Instance | 
               System.Reflection.BindingFlags.NonPublic).SetValue(panel1, true, null);
        //------------------------
        UpdateScrollbarsState();
    }        
    int imgWidth, imgHeight;
    Image image;
    Point leftTop = Point.Empty;
    int lastV, lastH;
    private void OpenImage(){
        OpenFileDialog openFile = new OpenFileDialog();            
        openFile.FileOk += (s, e) => {
            try {
                image = Image.FromFile(openFile.FileName);
                //calculate the physical size of the image based on the resolution and its logical size.
                //We have to do this because the DrawImage is based on the physical size (not logical).
                imgWidth = (int)(image.Width * 96f / image.HorizontalResolution + 0.5);
                imgHeight = (int)(image.Height * 96f / image.VerticalResolution + 0.5);
                lastV = lastH = 0;
                UpdateScrollbarsState();
                vScrollBar1.Value = 0;
                hScrollBar1.Value = 0;
                panel1.Invalidate();
            }
            catch {
                image = null;
                MessageBox.Show("Image file is invalid or corrupted!");
            }
        };
        openFile.ShowDialog();
    }
    private void UpdateScrollbarsState() {
        //We have to update all the info about Minimum and Maximum
        vScrollBar1.Minimum = 0;
        hScrollBar1.Minimum = 0;
        vScrollBar1.Maximum = Math.Max(imgHeight-panel1.Height,0);
        hScrollBar1.Maximum = Math.Max(imgWidth-panel1.Width,0);
        vScrollBar1.Visible = vScrollBar1.Maximum > 0;
        hScrollBar1.Visible = hScrollBar1.Maximum > 0;
        if (vScrollBar1.Maximum == 0) {
            leftTop.Y = 0;
            lastV = 0;
        }
        if (hScrollBar1.Maximum == 0) {
            leftTop.X = 0;
            lastH = 0;
        }
    }
    private void panel1_Paint(object sender, PaintEventArgs e) {
        if (image == null) return;
        e.Graphics.DrawImage(image, leftTop);
    }
    //The ValueChanged event handler of your vScrollBar1
    private void vScrollBar1_ValueChanged(object sender, EventArgs e) {
        if (!vScrollBar1.Visible) return;
        leftTop.Offset(0, -vScrollBar1.Value + lastV);
        lastV = vScrollBar1.Value;
        panel1.Invalidate();
    }
    //The ValueChanged event handler of your hScrollBar1
    private void hScrollBar1_ValueChanged(object sender, EventArgs e) {
        if (!hScrollBar1.Visible) return;
        leftTop.Offset(lastH - hScrollBar1.Value, 0);
        lastH = hScrollBar1.Value;
        panel1.Invalidate();
    }
    //handler for SizeChanged event of the panel. However if resizing
    //the form causes the panel's size changing, you should attach this 
    //handler for form.
    private void panel1_SizeChanged(object sender, EventArgs e) {
        UpdateScrollbarsState();
    }
    //handler for the Click event of a button (click to open an image)
    private void buttonOpenImage_Click(object sender, EventArgs e) {
        OpenImage();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM