面板openFileDialogue不会关闭 [英] panel openFileDialogue won't close

查看:116
本文介绍了面板openFileDialogue不会关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨。

我使用openFileDialogue在面板中打开了一张图片。它工作正常,背景图像被绘制到面板确定,但文件选择窗口没有关闭,只是让我选择更多的文件放入面板。

谢谢



Hi.
I have opened an image in the panel using openFileDialogue. It works fine and the background image is drawn into the panel ok, but the file selection window doesn''t close and just keeps letting me select more files to put into the panel.
Thanks

private void panel1_Paint(object sender, PaintEventArgs e)
{
    openFileDialog1.Filter = "JPEG IMAGES|*.jpg";
    openFileDialog1.InitialDirectory = "C:\\Users\\jason\\Documents\\IProject\\code\\imageAlign\\imageAlign\\bin\\Debug";
    openFileDialog1.Title = "Open Image";
    if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
   {
        panel1.BackgroundImage = Image.FromFile(openFileDialog1.FileName);
        Pen sb = new Pen(Color.Red,3);
        Graphics g = panel1.CreateGraphics();
        g.DrawRectangle(sb, 20, 20, 50, 50);
   }
}

推荐答案

从Paint事件中获取该代码!

只要系统需要绘制面板,就会调用paint事件。

因此,系统调用Paint,它会显示一个对话框,其中包含部分面板。

你关闭对话框,绘制矩形并退出 - 此时系统注意到对话框位置意味着需要重新绘制面板,所以它调用Paint,它会重新启动整个事件!





谢谢OringinalGriff - 我把它放入按钮点击事件中它运行正常。

但是,除非我有一个picturebox我看不到绘制的矩形。这是否意味着笔不能在面板中使用?




不,这意味着你做错了! :笑:



您需要做的是拆分代码:

Get that code out of the Paint event!
The paint event is called whenever the system needs to draw the panel.
So, the system calls Paint, which displays a dialog, which covers part of the panel.
You close the dialog, draw the rectangle and exit - at which point the system notices that the dialog position means the panel needs to be redrawn, so it calls Paint, which starts the whole thing off again!


"Thanks OringinalGriff - I put it into a button click event and it worked fine.
But, unless I have a picturebox I can''t see the drawn rectangle. Does this mean that the pen can''t be used in a panel?"


No, it means you are doing things wrong! :laugh:

What you need to do is split the code:
openFileDialog1.Filter = "JPEG IMAGES|*.jpg";
openFileDialog1.InitialDirectory = "C:\\Users\\jason\\Documents\\IProject\\code\\imageAlign\\imageAlign\\bin\\Debug";
openFileDialog1.Title = "Open Image";
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
    panel1.BackgroundImage = Image.FromFile(openFileDialog1.FileName);
    }

进入你的按钮点击处理程序,添加了一个(可能是不必要的,但这是一个好主意)

goes in your button click handler, with the addition of a (probably unnecessary but it''s a good idea)

panel1.Invalidate();

这会强制系统重绘面板,这会导致Paint事件发生。

在Paint事件中绘制矩形,但是您的代码中的一些小变化:

This forces the system to redraw the panel, which causes the Paint event to happen.
In the Paint event you draw the rectangle, but with a couple of small changes from your code:

using (Pen sb = new Pen(Color.Red,3))
   {
   e.Graphics.DrawRectangle(sb, 20, 20, 50, 50);
   }

你不需要在paint事件中创建一个图形对象 - 它已经在PaintEventArgs中为你提供了。

如果你构造一个Pen对象,你应该让它成为一个类级私有变量,或者自己处理它(使用块为你做),因为它们(和Graphics)上下文是稀缺的资源,在垃圾收集者为您处置它们之前会耗尽很长时间。





我现在很兴奋,想尝试把它放到课堂上:)

我创建了一个课程




You don''t need to create a graphics object in a paint event - it is already there for you in the PaintEventArgs.
If you construct a Pen object, you should either make it a class level private variable, or Dispose of it yourself (the using block does it for you) as they (and Graphics contexts) are scarce resources which will run out a long time before the Garbage Collector gets in to dispose them for you.


"I''m excited now and would like to try and put this into a class :)
I have created a class


class rectangle
{

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        using (Pen sb = new Pen(Color.Red, 3))
        {
            e.Graphics.DrawRectangle(sb, 20, 20, 50, 50);
        }





但不知道在方法调用中传递什么?





But don''t know what to pass in the method call?"

rectangle mc = new rectangle();





我不会惊讶你不知道要通过什么 - 这不是你想要做的。



退后一步,想一想:为什么长方形应该知道它所包含的面板?它会一直放在面板上吗? />


当然不会!例如,它可以直接放在表格上。但这个想法很好 - 让矩形负责绘图本身就是个好主意。

但是首先 - 类应该以大写字母开头,并且.NET中已经有一个Rectangle类,所以我们称之为MyRectangle,是吗?



I''m not surprised you don''t know what to pass - it''s not quite what you want to do.

Take a step back, and think about it: why should a rectangle know about the panel it is contained in? Will it always be on a panel?

Of course it won''t! It could be directly on a form, for example. But the idea was good - making the rectangle responsible for drawing itself is an excellent idea.
But first - Classes should begin with an Upper case letter, and there is already a Rectangle class in .NET, so lets call it a MyRectangle instead, yes?

public class MyRectangle
    {
    public Rectangle Rect { get; set; }
    public MyRectangle(Point p, Size s)
        {
        Rect = new Rectangle(p, s);
        }

    public void Draw(Graphics g, Pen p)
        {
        g.DrawRectangle(p, Rect);
        }



然后,您所要做的就是创建实例并绘制它们:


Then, all you have to do is create instances and draw them:

private List<MyRectangle> rects = new List<MyRectangle>();
Random r = new Random();
Pen pen = new Pen(Brushes.Red, 2);
private void butAddARectangle_Click(object sender, EventArgs e)
    {
    Point p = new Point(r.Next(10, 100), r.Next(10, 100));
    Size s = new Size(r.Next(10, 50), r.Next(10, 50));
    rects.Add(new MyRectangle(p, s));
    MyPanel.Invalidate();
    }

private void MyPanel_Paint(object sender, PaintEventArgs e)
    {
    foreach (MyRectangle mr in rects)
        {
        mr.Draw(e.Graphics, pen);
        }
    }

将该代码添加到表单中,并将这两个事件挂钩。



当你提供一个上下文和一个合适的笔时,你的MyRectangle类现在可以自己绘制。

它有一个构造函数,它可以获取所需的最少信息以便存在。



因此,每次按下按钮,它都会创建一个新的矩形,将其添加到列表中,并将它们全部绘制。

试试吧!看看会发生什么。





哇!现在我真的很喜欢!这是一段相当复杂的代码我已经将第一部分添加到创建的新类MyClass(以大写开头:) :)

你写的第二部分是''公共部分类Form1 :表格''页面。

我需要'勾起''。你的意思是打电话给班级 - 比如''MyRectangle mc = new MyRectangle();''?

对不起 - 我是新手柠檬。



当你说我需要上下文和合适的笔时,你的意思是:


Add that code to your form, and hook up the two events.

Your MyRectangle class can now draw itself, when you hand it a context and a suitable pen.
It has a constructor which takes the minimum info it needs in order to exist.

So, every time you press the button, it creates a new rectangle, adds it to the list, and paints them all.
Try it! See what happens.


"wow! Now I''m really kazoonked! That is quite a complex piece of code for little ol'' me. I have added the first part to the new class created, MyClass (with a capital beginning :))
And the second part you wrote to the ''public partial class Form1 : Form'' page.
I need to ''hook them up''. Do you mean call the class - like ''MyRectangle mc = new MyRectangle();''?
Sorry - I''m newbie lemon.

When you say I need to had it context and a suitable pen, do you mean this:

using (Pen sb = new Pen(Color.Red,3))
   {
   e.Graphics.DrawRectangle(sb, 20, 20, 50, 50);
   }







我想知道我是否应该解释一下我要做的事情,以确保我们在同一页面上。

我在表单的背景中打开图像后,我将扫描它的不同部分,以总结每个部分中的像素值。如果每个部分中的像素值高于某个阈值集,则应该在该部分上方/周围绘制矩形,突出显示该矩形,以便人们知道它高于阈值。我们还在正确的轨道上OriginalGriff吗?




不打电话给他们,不 - 第一个是Button Click事件处理程序方法 - 你需要将它挂钩到一个按钮,这样当你点击它时,该方法就会被调用。很容易做到 - 如果你把方法粘贴到你的表格中,在设计师中添加一个按钮并查看按钮的属性单击窗格中的事件按钮(它看起来像一个小亮点)并在列表中找到Click处理程序。打开Click一词右侧的下拉列表,然后从列表中选择方法。



第二个是Panel Paint事件处理程序,因此您可以将代码粘贴到现有代码中,或者以与上面按钮相同的方式挂钩事件。



我们还在正确的轨道吗?是的 - 它会正常工作 - 只需将相应的矩形添加到列表中它就会将它们绘制在你的位置想要(并且你可以显示多个矩形)



它看起来像很多代码,但它真的很简单 - 它只是你是新的而且看起来很复杂。它不是,老实说!






I wonder if I should explain what I am trying to do overall to be sure we are on the same page.
After I have opened the image in the background of the form I will scan different sections of it to sum up the pixel values in each section. If the pixel values in each section are above a certain threshold set then the rectangle should be drawn over / around that section highlighting it so that people would know it is above the threshold. Are we still on the right track OriginalGriff?"


Not call them, no - the first is a Button Click event handler method - you need to "hook it up" to a button, so that when you click it, the method gets called. Easy to do - if you have the method pasted into you form class, add a button in the designer and look at the button''s Properties pane. Click the "Events" button in the pane (it looks like a little lightening bolt) and find the "Click" handler in the list. Open the dropdown to the right of the word "Click" and select the method from the list.

The second is Panel Paint event handler, so you can paste the code into your existing one, or hook the event the same way you did for the button above.

Are we still on the right track? Yes - it''ll work fine - just add the appropriate rectangles to the list and it''ll draw them where you want (and you can have more than one rectangle showing as well)

It looks lioke a lot of code, but it''s pretty simple stuff really - it''s just that you are new and it looks complicated. It''s not, honest!

public Rectangle Rect { get; set; }

这只是在MyRectangle类中创建一个外部世界可以与之交互的属性。编译器会为您处理实际的存储空间,因此很容易创建。如果你认为它在课堂上是一个 public 变量,你现在就可以了(它不是,它比那更强大和有用)但是你会在你的课程中找到他们的后者) - 目前,只要接受类变量应该是 private ,如果你想要这个世界就写这样的在课堂外可以访问它们。



This just creates a Property in the MyRectangle class which the outside world can interact with. The compiler takes care of the actual storage for you, so it''s easy to create. If you think of it as a public variable in the class you will be fine for the moment (it isn''t, it''s a lot more powerful and useful than that but you''ll come to them latter in your course) - for the moment, just accept that class variables should be private, and write them like this if you want the world outside the class to be able to access them.

public MyRectangle(Point p, Size s)
    {
    Rect = new Rectangle(p, s);
    }

这是一个构造函数 - 它创建一个MyRetctangle类的新实例就像

This is a constructor - it creates a new instance of the MyRetctangle class just like

public MyRectangle(){}

会这样做,但是它允许你在创建数据时指定数据:所以不要使用

would do, but it allows you to specify the data when you create it as parameters: so instead of using

MyRectangle mr = new MyRectangle();
mr.Rect = new Rectangle(p, s);

您可以在一行中完成。由于没有位置或大小的矩形如果几乎无用,只有一个构造函数需要你提供参数才有意义。



you can do it in a single line. Since a rectangle with no location or size if pretty much useless it makes sense to only have a constructor that requires you to provide the parameters.

public void Draw(Graphics g, Pen p)
    {
    g.DrawRectangle(p, Rect);
    }

只是MyRectangle类中的一个方法,可以从外部调用。它只是在它的当前位置和大小绘制实际矩形。外部世界通过它传入的Graphics上下文指定绘制的位置,并且通过其他参数绘制whith。

Just a method in the MyRectangle class that can be called from outside it. All it does is draw the actual rectangle at it''s current location and size. The outside world specifies where it is to draw via the Graphics context it passes in, and teh pen it is to draw whith via the other parameter.

private List<MyRectangle> rects = new List<MyRectangle>();

Thos可能有点复杂......它声明了一个名为 rects 的私有变量,它可以容纳许多MyRectangle对象。你不必告诉它持有多少,它并不在乎 - 它只是为你记住它们。再次,你将来看这些(并且可能使用它们*很多*) - 如果你知道一个数组是什么,把它想象成一个数组,你不需要说它有多大 - 它不是'什么都不是这样,但它现在会做的!

Thos might be a bit more complicated... It declares a private variable called rects that can hold a number of MyRectangle objects. You don''t have to tell it how many it is to hold, it doesn''t care - it just remembers them for you. Again, you will come to these later (and probably use them a *LOT*) - if you know what an array is, think of it as an array where you don''t need to say how big it is - it isn''t anything like that, but it''ll do for the moment!

Random r = new Random();

只需设置好所以我以后可以使用随机数生成器,所以我的新矩形都不一样......

Just sets things up so I can use a random number generator later, so my new rectangles aren''t all the same...

Pen pen = new Pen(Brushes.Red, 2);

轻松:只是你的线移动到班级变量。

Easy-peasy: It''s just your line moves to a class level variable.

private void butAddARectangle_Click(object sender, EventArgs e)
    {
    ...
    }

Button Click事件处理程序 - 我认为你已经遇到过这些。

Button Click event handler - you have met these already, I think.

Point p = new Point(r.Next(10, 100), r.Next(10, 100));
Size s = new Size(r.Next(10, 50), r.Next(10, 50));

使用随机信息创建一个新的Point和Size对象。 r.Next 位说从我们之前创建的r随机数生成器中给我下一个随机数和 10,100 只是将它生成的数字限制在10到99之间(包括10和99)。 (所以它们不是太大或太小)

Creates a new Point and Size object using random info. The r.Next bit says "give me the next random number from the "r" random number generator we created earlier" and the 10,100 just restricts the numbers it generates to be between 10 and 99 inclusive. (So they aren''t too big, or too small)

rects.Add(new MyRectangle(p, s));

创建一个新矩形,并将其添加到列表中以供日后使用。

Creates a new rectangle, and add it to the list for later.

MyPanel.Invalidate();

告诉系统重绘Panel,方法是调用它的Paint事件。

Tells the system to redraw the Panel, by calling it''s Paint event.

private void MyPanel_Paint(object sender, PaintEventArgs e)
    {
    ...
    }

绘制事件处理程序 - 你已经遇到过这些了!

Paint event handler - you have met these!

foreach (MyRectangle mr in rects
    {
    ...
    }

循环遍历列表中的每个MyRectangle对象,每次循环指定其中一个它们到变量 mr - 你可能已经遇到过这些。

Loop through each of the MyRectangle objects in the list and each time round assign one of them to the variable mr - you have probably met these already.

mr.Draw(e.Graphics, pen);

在变量 mr中调用MyRectange实例上的Draw方法





基督!写起来要比解释容易得多!:笑:

Calls the Draw method on the MyRectange instance in the variable mr


Christ! It''s a lot easier to write than to explain! :laugh:


这篇关于面板openFileDialogue不会关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆