» »

[c#] Risanje z miško

[c#] Risanje z miško

japol ::

Imam kodo, kjer rišem na nek pictureBox4 in v Bitmap. Imam metode za MyMouseDown, MyMouseUp, MyMouseMove,... vse v Form1.cs
in
protected override void OnLoad(System.EventArgs e)
        {
            pictureBox4.MouseDown += new MouseEventHandler(risanje1_MyMouseDown);
            pictureBox4.MouseUp += new MouseEventHandler(risanje1_MyMouseUp);
            pictureBox4.MouseMove += new MouseEventHandler(risanje1_MyMouseMove);
        }

Ker je nastalo precej te kode, želim to vstaviti v nek novi class, (npr.: Class3.sc). Problem nastane, ker void "OnLoad" deluje na Form1.cs, ne pa na nekem poljubnem class-u. Kam se v bistvu ti eventi praviloma vpisujejo da se jih poveže? Kakšen primer?

darkkk ::

če narediš vse prav, pol namesto:
pictureBox4.MouseDown += new MouseEventHandler(risanje1_MyMouseDown);

uporabiš:
pictureBox4.MouseDown += new MouseEventHandler(Class3.risanje1_MyMouseDown);


Parameter event handlerja je funkcija, ki hočeš, da se izvede ob eventu. Torej mu moraš povedat, kam naj jo gre iskat. (Pa fajn je, če maš to v nekem drugem classu in imaš noter samo funkcije, da je ta class statičen in metode v njem statične - sicer moraš naredit instanco razreda preden kličeš "nestatično" metodo). Jasno pa, vprašanje kako boš stvari implementiral, načeloma tvoj class3 nima dostopa do private živali v tvoji formi/picboxu.

japol ::

Se pravi da ta del kode ("OnLoad") mora vedno biti na Form1.sc? Se pravi da s tem povežem evente iz nekega drugega classa s Form1.cs? Ali se da vse evente na tak način povezati ali je kakšna posebnost; mislm , če lahko vedno delam tako: ...Handler(Class3....... ?

darkkk ::

Kolk maš kaj izkušenj z OOP. Načeloma pri formah maš okvirno:
1. konstruktor (ko kreiraš instanco forme)
2. OnLoad ... približno takrat, ko se forma prikaže (tle lahko učim malo krive vere, ampak se izvede preden je forma na zaslonu)
3. OnClose ... ko zapreš formo (alt+f4 oz. kako drugače)
4. destruktor

In jasno, OnLoad je metoda razreda Form v lasti instance Form1. Ampak lahko tu noter kličeš karkoli iz Class3. Problem je, Class3 nima dostopa do private "elementov" tvojega Form1.


Načeloma jaz tako delam: "algoritme", ki so neodvisni od forme pišem drugam, kar je v lasti forme oz. manipulira s formo pa kar v Form1, zato pridejo prav regioni :) Načeloma nekaj, kar riše po formi paše v lastnino dotične forme.

Zgodovina sprememb…

  • spremenil: darkkk ()

japol ::

In če nimam "OnLoad", kam pa kako potem pišem to kodo:
pictureBox4.MouseDown += new MouseEventHandler(Class3.risanje1_MyMouseDown);
(dam pod InitializeComponent(); ali kam?

Zaradi preglednosti poskušam vse spraviti v classe, primer: Class1 je izračun, class2 je priprava poročila, class3 ,... in se vsakemu posvetim. Form1 pa uporabim samo da poveže te classe v celoto, tako da v Form1 ni skoraj nič kode. In potem ko se vstavi nek novi element npr. Izračun2, le dodam class in le tu pišem kodo. Se pravi da obdržim celoto na enem classu, ne pa da imam nekje metodo, drugje pa spremenljivke. Men je tko bol pregledno. Hvala ti za pomoč, zvečer to preverim, pa sporočim.

darkkk ::

Karkol moraš dat pod InitializeComponent(), ampak le-ta je v konstruktorju, ne na OnLoad. Če ne veš točno kaj delaš, pusti InitializeComponent() na miru.

Če greš gledat Form1.Designer.cs datoteko, maš noter funkcijo InitializeComponent, v njej je zgenerirana koda, ki jo dobiš z dodajanjem komponent na formo.


Kaj bi ti rad naredu je, da bi ti event mousedown neki izvajal?

narediš tko: (oz. jaz bi naredil tako)
Dodaš komponenti picBox4 eventhandler
picBox4.MouseDown += new EventHandler(PicBoxMouseDown);

napišeš kratek event handler, ki bo poklical golomazno veliko funkcijo, ki je doma nekje drugje
private void PicBoxMouseDown(object sender, EventArgs e){
    //karkoli rabiš prej
    Class3.HandlePicBox4((PictureBox)sender, EventArgs e /*, dodatna navlaka*/)
    //če je šlo kaj narobe etc
}


V Class3 greš napisat funkcijo, ki dobi za parametre referenco na picBox, argumente in morda še kaj in nekaj počne s tem pictureboxom.

public static void HandlePicBox4(PictureBox picBox, EventArgs e /*, ostalo*/){
 //Dela karkoli že, verjetno riše neke krivulje :)
}


Tko nekako bi jaz zapakiral te stvari.

popravil st.koda, itd

Zgodovina sprememb…

  • spremenil: darkkk ()

japol ::

Podčrta mi:
pictureBox4.MouseDown += new MouseEventHandler(Class3.risanje1_MyMouseDown);

Napaka je:
An object reference is required for the non-static field, method, or property Class3.risanje1_MiškaDol(object, System.Windows.Forms.MouseEventArgs)

darkolord ::

Si naredil public static void?

japol ::

ne smem, ker imam globalne spremenljivke, potem mi pa njih podčrta. morjo pa bit globalne.

darkolord ::

Ja potem pa rabiš delegat in eno instanco do Class3.

japol ::

V Class3 imam kodo:
class Class3
    {
        Boolean RisanjeČrte = false;
        Boolean RisanjeKroga = false;
        Boolean OpisSlike = false;

        Boolean BrisalecSlike = false;
       
        private System.Drawing.Drawing2D.GraphicsPath potMiške = new System.Drawing.Drawing2D.GraphicsPath();

      Rectangle nakazovalniPravokotnik = new Rectangle();

        Point začetnaTočka = new Point();
        Point končnaTočka = new Point();

        Bitmap slika5;

        Form1 f1 = new Form1();

        public void risanje1_MiškaDol(Object sender, MouseEventArgs e)
        {
            if (RisanjeČrte == true)
            {
.............................
}
}

v Form1 imam kodo:
        // Set up delegates for mouse events.
        protected override void OnLoad(System.EventArgs e)
        {
            pictureBox4.MouseDown += new MouseEventHandler(Class3.risanje1_MiškaDol);

        }

ampak mi javi error:
An object reference is required for the non-static field, method, or property Class3.risanje1_MiškaDol(object, System.Windows.Forms.MouseEventArgs)

Sprememnjivke ne smem imeti static, ker jih potrebujem v risanje1_MiškaDol, risanje1_MiškaGor, risanje1_Premikanje, itd.

darkolord ::

Če Class3 ni statičen, potem rabiš do njega referenco. Jo že imaš kje?

japol ::

Poizkusil sem z:
na Form1 imam kodo:
  protected override void OnLoad(System.EventArgs e)
        {
            Class3 Class3Risanje = new Class3();
            pictureBox4.MouseDown += new MouseEventHandler(Class3Risanje.risanje1_MiškaDol);
            pictureBox4.MouseUp += new MouseEventHandler(Class3Risanje.risanje1_MiškaGor);
            pictureBox4.MouseMove += new MouseEventHandler(Class3Risanje.risanje1_MiškaPremikanje);
        }

ampak ni v redu, ni napake, nič se pa tudi ne zgodi.

darkolord ::

Kaj bi se pa moralo zgoditi?

japol ::

Zgoditi bi se moralo to, da lahko rišem z miško katere koda je v classu3

V class3 je koda:
class Class3
    {
        Boolean RisanjeČrte = false;
        Boolean RisanjeKroga = false;
        Boolean OpisSlike = false;
        Boolean BrisalecSlike = false;
        private System.Drawing.Drawing2D.GraphicsPath potMiške = new System.Drawing.Drawing2D.GraphicsPath();
      Rectangle nakazovalniPravokotnik = new Rectangle();
        Point začetnaTočka = new Point();
        Point končnaTočka = new Point();
        Bitmap slika5;
        Form1 f1 = new Form1();
        public void risanje1_MiškaDol(Object sender, MouseEventArgs e)
        {
            if (RisanjeČrte == true)
            {
//koda za miško dol
}
}


ta koda deluje, če jo imam na Form1 ampak zaradi preglednosti sem jo dal na svoj class, rišem pa na picturebox4

in na Form1 imam kodo:
protected override void OnLoad(System.EventArgs e)
      {
          Class3 Class3Risanje = new Class3();
          pictureBox4.MouseDown += new MouseEventHandler(Class3Risanje.risanje1_MiškaDol);
          pictureBox4.MouseUp += new MouseEventHandler(Class3Risanje.risanje1_MiškaGor);
          pictureBox4.MouseMove += new MouseEventHandler(Class3Risanje.risanje1_MiškaPremikanje);
      }

ampak ne deluje.

darkolord ::

Kje pa imaš v Class3 referenco nazaj na Form1?

japol ::

na tak način:
class Class3
    {
        Boolean RisanjeČrte = false;
        Boolean RisanjeKroga = false;
        Boolean OpisSlike = false;
        Boolean BrisalecSlike = false;
        private System.Drawing.Drawing2D.GraphicsPath potMiške = new System.Drawing.Drawing2D.GraphicsPath();
      Rectangle nakazovalniPravokotnik = new Rectangle();
        Point začetnaTočka = new Point();
        Point končnaTočka = new Point();
        Bitmap slika5;
        Form1 f1 = new Form1();
        
public void risanje1_MiškaDol(Object sender, MouseEventArgs e)
        {
            if (BrisalecSlike == true)
            {
                if (e.Button == MouseButtons.Left)
                {
                    Graphics graphics = f1.pictureBox4.CreateGraphics();
                    int velikostRadirke = System.Int32.Parse(f1.textBox27.Text);
                    graphics.FillRectangle(new SolidBrush(Color.White), e.X, e.Y, velikostRadirke, velikostRadirke);
                    Rectangle oblikaRadirke = new Rectangle(e.X, e.Y, velikostRadirke, velikostRadirke);
                }
            }
}

darkolord ::

"f1" ni ista forma kot tista, na kateri si kliknil.

Tole:

Form1 f1 = new Form1();


Zamenjaj z:

Form1 f1;

public Class3(Form1 form)
{
    f1 = form;
}


Tole:

Class3 Class3Risanje = new Class3();


Pa z:

Class3 Class3Risanje = new Class3(this);

japol ::

Tudi to ne deluje. Z brakpointi pridem do if (BrisalecSlike == true), in preskoči na naslednji if, ne izvede pa kar je znotraj tega if. In enako dobim z mojo varianto in tvojo.

darkolord ::

Ja BrisalecSlike je očitno na false ane.

MH0 ::

Če te muči samo nepreglednost kode jo pač razdeliš v več datotek.

darkkk ::

Dejmo se mal zmenit:
ti bi rad na nek picbox neki risal ko maš klik dol, za to bi rad uporabljal neko funkcijo "od nekje drugje".

Torej: na picboxu moraš lovit event, ko je miškin gumb dol ter ...

Če živi funkcija nekje zunaj in dela nekaj na picboxu, mora vedet na kateri picbox oz. na katero formo naj packa oz. če je to forma pač forme.

Torej mora bodisi class3 že (najbolje v konstruktorju) dobit noter referenco na formo, ali pa pišeš statičen class pa statične metode.

Zgodovina sprememb…

  • spremenil: darkkk ()

japol ::

Mi je uspelo. Problem je bil, ker sem imel enake spremenjivke definirane na Form1 in Class3. Res je na false je blo vse skos. Pa moral sem uporabiti.
Form1 f1;
public Class3(Form1 form)
{
    f1 = form;
}

da mi ne kreira na novo forme.
Predolgo že to gledam, ne vem kako sem lahko kaj takega spregledal. Očitno rabm konkreten dopust :).
darkkk: hvala ti za potrplenje.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

c# form

Oddelek: Programiranje
131747 (1261) FuI2cY
»

[c#] ukaz radirka

Oddelek: Programiranje
91038 (831) japol
»

[c#] picturebox, slika na sliko

Oddelek: Programiranje
151010 (820) japol
»

c# class

Oddelek: Programiranje
342154 (1748) japol
»

Akcije nad grafiko v VB

Oddelek: Programiranje
81188 (1001) damijani

Več podobnih tem