2016-02-09 5 views
5

Я разрабатываю игру HangMan, чтобы узнать, как использовать C# с DevExpress. Моя проблема заключается в том, что я рисую сообщение с размером относительно размера панели, в которую я его вставляю, так что его размер пересчитывается, если размер окна изменяется. Мой код выглядит так:Изображение дублируется, когда окно максимально

namespace HangMan 
{ 
    public partial class HangMan : Form 
    { 
    public HangMan() 
    { 
     InitializeComponent(); 
     this.Paint += new System.Windows.Forms.PaintEventHandler(HangMan_Paint); 
    } 

    void drawHangPost() 
    { 

     //Use panel size percentages to draw the post 
     double dWidth = pnlHang.Width; double dHeight = pnlHang.Height; 

     int x1 = (int)Math.Round(0.8 * dWidth); int x2 = (int)Math.Round(0.45 * dWidth); 
     int y1 = (int)Math.Round(dHeight); int y2 = (int)Math.Round(0.23 * dHeight); 
     int xInit = x1; int xFinal = x1 - x2; 
     int yInit = y1; int yMiddle = 10; int yFinal = y2; 

     //Paint Post 
     Graphics g = pnlHang.CreateGraphics(); 
     Pen p = new Pen(Color.Brown, 10); 

     g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle)); 
     g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle)); 
     g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal));  
    } 

    private void HangMan_Paint(object sender, EventArgs e) 
    { 
     drawHangPost(); 
    }   
    } 
} 

Это отлично работает для меня, а размер чертежа изменяется. Однако, когда я изменяю размер окна вручную, на каждом шаге нарисован новый пост, поэтому многие из них появляются. Если я максимизирую окно, появятся два столбца двух разных размеров.

Тем не менее, когда я сворачиваю окно и открываю его снова, остается только правильный рисунок. Есть ли способ эриентировать предыдущие рисунки, когда нарисован новый?

Должен ли я включать какую-то команду эзотерики писать после InitializeComponent()?

+2

Попробуйте 'pnlHang.Invalidate()' в событии OnResize формы. – SimpleVar

+3

Как @SimpleVar говорит или использует свойство 'Control.ResizeRedraw' - – adv12

+0

@ adv12 Это хорошая собственность, которая не знала этого - thx! : D – SimpleVar

ответ

4

Так большая часть вашей проблемы вы реагировать на события краски формы, а затем картину на элемент управления, который может или не может быть признан недействительным.

Вместо этого вы должны подписаться на событие краски панели и сделать свою картину там с объектом Graphics, который передается в аргументы событий. Также вы захотите обработать событие изменения размера панели, чтобы аннулировать его. Я предполагаю, что вы используете либо привязки, либо стыковку, чтобы автоматически изменять размер панели при изменении размера формы. Если нет, вам нужно изменить его так, чтобы панель изменялась в зависимости от формы.

public Form1() 
    { 
     InitializeComponent(); 

     pnlHang.Paint += PnlHangPaint; 
     pnlHang.Resize += (sender, args) => pnlHang.Invalidate(); 
    } 

    private void pnlHang_Paint(object sender, PaintEventArgs paintEventArgs) 
    { 
     drawHangPost(paintEventArgs.Graphics); 
    } 

    void drawHangPost(Graphics g) 
    { 
     //Use panel size percentages to draw the post 
     double dWidth = pnlHang.Width; 
     double dHeight = pnlHang.Height; 

     int x1 = (int)Math.Round(0.8 * dWidth); 
     int x2 = (int)Math.Round(0.45 * dWidth); 
     int y1 = (int)Math.Round(dHeight); 
     int y2 = (int)Math.Round(0.23 * dHeight); 
     int xInit = x1; 
     int xFinal = x1 - x2; 
     int yInit = y1; 
     int yMiddle = 10; 
     int yFinal = y2; 

     //Paint Post 
     using (Pen p = new Pen(Color.Brown, 10)) 
     { 
      g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle)); 
      g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle)); 
      g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal)); 
     } 
    } 

Кроме того, в любое время, когда вы создаете ресурс GDI, например ручку или кисть, не забудьте их уничтожить! С помощью блока C# это хорошо для вас.

+0

Это работает красиво, и код намного более организован. Спасибо, я многое узнал из ответа! @Erik – Slash

-1

Ваша проблема в том, что вы снова и снова используете один и тот же элемент управления. Простым решением было бы заполнить прямоугольник, который рисует предыдущее изображение. Это сделает фрейм флэш часто, так что я делаю, чтобы решить это, чтобы создать новый битмап и нарисовать его. Затем я рисую скомпилированное растровое изображение на панели.

public void Draw(Graphics g){ 
Bitmap canvas = new Bitmap(pnlHang.Width, pnlHang.Height); 
Graphics canvg = Graphics.FromImage(canvas); 
canvg.FillRectangle(Brushes.Black, new Rectangle(new Point(0, 0), pnlHang.Size); 
//Draw using canvg 
canvg.Dispose(); 
g.DrawImage(canvas, new Rectangle(new Point(0, 0), pnlHang.Size)); 
} 
+1

Это вряд ли поможет. Причина, по которой предыдущая графика не перезаписана, заключается в том, что только часть элемента управления была аннулирована. Когда вы обрабатываете событие «Paint», сделанный вами рисунок привязывается к прямоугольнику, который был признан недействительным. Кроме того, если вам нужна двойная буферизация, которая, похоже, является тем, что вы пытаетесь, класс 'Control' имеет встроенный. Просто установите свойство« DoubleBuffered »в элементе управления и объект« Graphics », который вы получите в' Paint 'будет для заднего буфера. – adv12

+0

Хорошо, это очень интересно. Благодарю. – frogmannick

Смежные вопросы