2013-07-31 83 views
1

我使用的是面板显示在Windows中的图像形成 我在Panel_Paint事件面板绘制图片如下:面板和滚动条在Windows窗体

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

现在,图像绘制为我预计,图像底部的某些部分不显示,因为它的高度大于窗体高度。 我已经添加了VScrollBar。如何使用该面板在VScrollBar的帮助下查看图像的其余部分。

+2

的Panel.VerticalScroll属性提供了所需的行为 –

+1

@ViacheslavSmityukh但是我认为它不适用于自定义绘图。 –

回答

3

此解决方案,但是,如果你的形象是足够大的,有一点点闪烁滚动时(但它是可以接受的)。首先,您必须在面板右侧添加VScrollBar,并在面板底部右侧添加HScrollBar。该演示需要你有一个名为VScrollBarvScrollBar1名为HScrollBarhScrollBar1,一个名为buttonOpenImage允许用户打开一些图像Button,作为主要区域绘制图像的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(); 
    } 
} 
+0

滚动条应该添加到窗体还是面板? – Kira

+0

@Anand并不重要。但是你应该注意到,如果在面板上添加滚动条,它会稍微隐藏图像,除非你减去滚动条的'Maximum'的某个偏移量。我更新了上面的一些修补程序(现在更完整),您可以自己复制并尝试。当然,可能有一些错误(Winforms实际上是bug,需要很多测试和修复),但它应该很少。我现在主要关注*** WPF ***。 “Winforms”是我过去感兴趣的领域,如果它是必须做的,我只是在一些Winforms项目上工作。 –

+0

感谢您的回复,我会尽力而为 – Kira

5

您可以使用PictureBox并将SizeMode设置为Panel的AutoSize和AutoScroll属性。这样面板应该添加滚动条,如果需要的话。

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); 
+0

他想绘制他的形象,而不是使用picturebox。 –

+1

他想要画出自己的形象而陷入困境。完全不清楚他为什么要这样做,这个答案给出了一个体面的解决方案。 –