Windows From, klawisz TAB wymazuje rysowane linie

0

Witam
Mam problem, rysuje na formie wykres lecz po naciśnięciu TAB on znika. Po kolejnym narysowaniu(przyciskiem) już ten efekt nie występuje. W dodatku jeżeli przed pierwszym rysowaniem nacisnę TAB a później narysuje to po kolejnym TAB wykres nie znika. Co mogę z tym zrobić ?

Do klasy wykres przekazuje grafikę w konstruktorze formy w taki sposób.

 wykres = new Wykres(this.CreateGraphics());
0

pokaż więcej kodu.

0

Plik exe z tym efektem: http://www40.zippyshare.com/v/33609931/file.html

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Lab02Final
{
    public partial class glowneOkno : Form
    {
        private ZestawUczacy zestaw;
        private Neuron neuron;
        private Nauczyciel nauczyciel;
        private Wykres wykres;
        
        public glowneOkno()
        {
            InitializeComponent();
            zestaw = new ZestawUczacy(25);
            neuron = new Neuron(0.1, 100);
            nauczyciel = new Nauczyciel();
            wykres = new Wykres(this.CreateGraphics());
            IdzDoSzkoly();
        }

        private void IdzDoSzkoly()
        {
            DodajProbki();
            wykres.WypelnijWagi(txbW0, txbW1, txbW2, neuron);
            nauczyciel.Nauczaj(neuron, zestaw);
        }

        private void buttonRysuj_Click(object sender, EventArgs e)
        {
            wykres.RysujWykres();
            wykres.RysujZestawTestowy(zestaw);
            wykres.WypelnijWagi(txbW0, txbW1, txbW2, neuron);
            wykres.ObliczINarysujNaPodstawieWag(neuron);
        }

        private void buttonOblicz_Click(object sender, EventArgs e)
        {
            if (txbX1.TextLength > 0 && txbX2.TextLength > 0)
            {
                int x, y;
                try
                {
                    x = Int32.Parse(txbX1.Text);
                    y = Int32.Parse(txbX2.Text);
                }
                catch (FormatException)
                {
                    return;
                }
                finally
                {
                    txbX1.Clear();
                    txbX2.Clear();
                }
                
                int wynik = neuron.Oblicz(x, y);
                txbWynik.Text = wynik.ToString();
                wykres.RysujPunktWyniku(x, y, wynik);
            }
        }

        private void DodajProbki()
        {
            ////// Dodanie 25 probek (x, y, )//////
            zestaw.Dodaj(2, 10, 1);
            zestaw.Dodaj(-5, 9, 1);
            zestaw.Dodaj(-8, 7, 1);
            zestaw.Dodaj(-3, 7, 1);
            zestaw.Dodaj(2, 7, 1);
            //
            zestaw.Dodaj(4, 7, 1);
            zestaw.Dodaj(7, 6, -1);
            zestaw.Dodaj(-10, 4, 1);
            zestaw.Dodaj(-6, 3, 1);
            zestaw.Dodaj(-2, 4, 1);
            //
            zestaw.Dodaj(6, 4, -1);
            zestaw.Dodaj(-2, 2, 1);
            zestaw.Dodaj(2, 2, -1);
            zestaw.Dodaj(7, 2, -1);
            zestaw.Dodaj(-10, -4, 1);
            //
            zestaw.Dodaj(-7, -2, 1);
            zestaw.Dodaj(-2, -2, -1);
            zestaw.Dodaj(-4, -6, -1);
            zestaw.Dodaj(1, -4, -1);
            zestaw.Dodaj(4, -2, -1);
            //
            zestaw.Dodaj(8, -2, -1);
            zestaw.Dodaj(9, -3, -1);
            zestaw.Dodaj(8, -5, -1);
            zestaw.Dodaj(4, -5, -1);
            zestaw.Dodaj(-5, -5, -1);
            //////////////////////////
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}
 
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;


namespace Lab02Final
{
    class Wykres
    {
        private Graphics grafika;
        private int skala;

        public Wykres(Graphics grafika)
        {
            this.grafika = grafika;
            skala = 18;
        }

        public void RysujZestawTestowy(ZestawUczacy zestaw)
        {
            for (int i = 0; i < zestaw.zestaw.Count; i++)
            {
                if (zestaw.zestaw[i].d == 1)
                {
                    RysujCzerwonyPunkt("+", zestaw.zestaw[i].x1, zestaw.zestaw[i].x2);
                }
                else
                {
                    RysujCzerwonyPunkt("-", zestaw.zestaw[i].x1, zestaw.zestaw[i].x2);
                }
            }
        }

        public void RysujPunktWyniku(int x, int y, int wynik)
        {
            if (wynik == 1)
            {
                RysujNiebieskiPunkt("+", x, y);
            }
            else
            {
                RysujZielonyPunkt("-", x, y);
            }

        }

        public void RysujCzerwonyPunkt(string punkt, int x, int y)
        {
            int nowyX = PrzeliczXPunktu(x),
                nowyY = PrzeliczYPunktu(y);
            grafika.DrawString(string.Format("{0}({1},{2})", punkt, x, y), 
                                      new Font("Segoe UI Light", 10), Brushes.Red, nowyX, nowyY);
        }

        public void RysujNiebieskiPunkt(string punkt, int x, int y)
        {
            int nowyX = PrzeliczXPunktu(x),
                nowyY = PrzeliczYPunktu(y);
            grafika.DrawString(string.Format("{0}({1},{2})", punkt, x, y),
                                      new Font("Segoe UI Light", 10), Brushes.Blue, nowyX, nowyY);
        }

        public void RysujZielonyPunkt(string punkt, int x, int y)
        {
            int nowyX = PrzeliczXPunktu(x),
                nowyY = PrzeliczYPunktu(y);
            grafika.DrawString(string.Format("{0}({1},{2})", punkt, x, y), 
                                      new Font("Segoe UI Light", 10), Brushes.Green, nowyX, nowyY);
        }

        public void RysujWykres()
        {
            Pen black = new Pen(Color.Black, 1);
            
            grafika.DrawLine(black, new Point(250, 0), new Point(250, 450));
            grafika.DrawLine(black, new Point(0, 250), new Point(500, 250));

            int x1 = PrzeliczXLini(-12), y1 = PrzeliczYLini(-7),
                x2 = PrzeliczXLini(12), y2 = PrzeliczYLini(11);

            grafika.DrawLine(black, new Point(x1, y1), new Point(x2, y2)); // prosta

            RysujSkale(black);
            RysujStrzalki(black);
        }

        public void ObliczINarysujNaPodstawieWag(Neuron neuron)
        {
            Pen purple = new Pen(Color.Purple, 1);
            int x1 = -11, x2 = 12; //przykladowe
            
            int y1 = ObliczY(x1, neuron),
                y2 = ObliczY(x2, neuron);

            int nowyX1 = PrzeliczXLini(x1),
                nowyX2 = PrzeliczXLini(x2),
                nowyY1 = PrzeliczYLini(y1),
                nowyY2 = PrzeliczYLini(y2);

            grafika.DrawLine(purple, new Point(nowyX1, nowyY1), new Point(nowyX2, nowyY2));
        }

        public void WypelnijWagi(TextBox txbW0, TextBox txbW1, TextBox txbW2, Neuron neuron)
        {
            txbW0.Text = neuron.w0.ToString();
            txbW1.Text = neuron.w1.ToString();
            txbW2.Text = neuron.w2.ToString();
        }

        public int ObliczY(int x, Neuron neuron)
        {
            double wynik = (((-neuron.w1) / neuron.w2) * x) + (neuron.w0 / neuron.w2);
            return (int)wynik;
        }

        private void RysujSkale(Pen pen)
        {
            int krokX = 16, krokY = 16;
            
            for (int i = 0; i < 26; i++)
            {
                RysujKreske(pen, krokX, 245, krokX, 255);
                krokX += skala;
            }

            for (int i = 0; i < 24; i++)
            {
                RysujKreske(pen, 245, krokY, 255, krokY);
                krokY += skala;
            }
        }

        private void RysujKreske(Pen pen, int x1, int y1, int x2, int y2)
        {
            grafika.DrawLine(pen, new Point(x1, y1), new Point(x2, y2));
        }

        private void RysujStrzalki(Pen pen)
        {
            grafika.DrawLine(pen, new Point(469, 265), new Point(484, 250));
            grafika.DrawLine(pen, new Point(469, 235), new Point(484, 250));

            grafika.DrawLine(pen, new Point(250, -1), new Point(235, 16));
            grafika.DrawLine(pen, new Point(250, -1), new Point(265, 16));
        }

        public int PrzeliczXLini(int x)
        {
            return 250 + (x * skala);
        }

        public int PrzeliczXPunktu(int x)
        {
            return 244 + (x * skala);
        }

        public int PrzeliczYLini(int y)
        {
            return 250 - (y * skala);
        }

        public int PrzeliczYPunktu(int y)
        {
            return 240 - (y * skala);
        }
    }
}
0

Rysowanie nie powinno się odbywać w OnClick, tylko w OnPaint.
Najlepiej też nie rysuj po formie bezpośrednio, a lepiej po panelu jakimś.

Możesz też użyć kontrolki PictureBox, utworzyć jej bitmapę:

pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);

a potem rysować po tej bitmapie (nie po kontrolce bezpośrednio). Wtedy możesz rysować w OnClick.

Nie trzymaj obiektu Graphics przez cały czas. Po zakończeniu rysowania trzeba go zwolnić – albo przez wywołanie graphics.Dispose(), albo używając słowa using.

0

Jak takie rysowanie OnPaint miało by wyglądać? Czy to jakieś dodatkowe zdarzenie które mogę przypiąć do buttona?

Nawet nie wiedziałem że Graphics trzeba zwalniać, dzięki.
Za bardzo nie wiem gdzie użyć Dispose() albo using. Mógłbyś mi pokazać oba przypadki?

PS.
Doczytałem o tym OnPaint lecz po ang i nie jestem pewien. Czyli zdarzenie OnPaint wywołuje forma kiedy zostaje przerysowana, wynika z tego że ja mam przeładować to zdarzenie dodając dodatkowo rysowanie mojego wykresu ? Jeżeli tak to jak często taka forma jest przerysowywana ? Czy klikając klawisz TAB doświadczyłem własnie tego przerysowania?

protected override void OnPaint(PaintEventArgs e)
{
   base.OnPaint(e);
   wykres.RysujWykres();
   if(zestaw.CzyWypelniono() && rysujZestaw)
   {
       wykres.RysujZestawTestowy(zestaw);
   }
   if(neuron.CzyNauczono() && rysujNaPodstawieWag)
   {
       wykres.ObliczINarysujNaPodstawieWag(neuron); 
   }
}
0

Przerysowanie jest wywoływane gdy przesuniesz oknem, zmienisz rozmiar, albo przeciągniesz coś nad nią (kontrolka, forma). Możesz też wymusić przerysowanie formy.
Powinieneś przejmować graphics od argumentu i przekazywać dalej:

protected override void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;
    wykres.RysujWykres(g);
//.....
}

Jeżeli chodzi o wymuszenie przerysowania to możesz użyć Refresh()
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.refresh.aspx

1 użytkowników online, w tym zalogowanych: 0, gości: 1