我正在使用面板在Windows窗体中显示图像
我在Panel_Paint事件中的面板中绘制图像,如下所示:
Graphics g = panel1.CreateGraphics();
Image im = new Bitmap(@"../../Data/#3_Page2.PNG");
g.DrawImage(im,new Point(10,10));
现在,按照我的预期绘制图像,图像底部的某些部分由于高度大于表单高度而未显示。
我现在添加了VScrollBar。我如何使该面板在VScrollBar的帮助下查看其余图像。
最佳答案
此解决方案有效,但是,如果您的图像足够大,则滚动时会出现一点闪烁(但是可以接受)。首先,您必须在面板右侧添加一个VScrollBar
,在面板底部下方添加一个HScrollBar
。此演示要求您有一个名为VScrollBar
的vScrollBar1
和一个HScrollBar
的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();
}
}
关于c# - Windows窗体中的Panel和ScrollBar,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17970141/