Graficke objekty c# – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Graficke objekty c# – .NET – Fórum – Programujte.comGraficke objekty c# – .NET – Fórum – Programujte.com

 

Misiak0
Návštěvník
6. 4. 2010   #1
-
0
-

ahoj

chcel by som sa opytat ako by som mal zacat ked chcem urobit nieco ako selekciu grafickeho objektu.

Chcel by som spravit nieco ako je napr. v malovani pisanie textu, s tym ze kresliaca plocha by sa dala oznacit (pokliknuti na nu by sa objavili body) a tahom toho bodu by sa dala plocha zvacsit alebo zmensit.... ale neviem ako postupovat pri oznaceni tej plochy, vedel by niekto poradit pls?
dik

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
6. 4. 2010   #2
-
0
-

Otázkou je, co si představuješ pod pojmem grafický objekt. Když zmiňuješ Malování a kreslící plochu (+ další "popis"), tak asi míříš do končin, kde si "všechno" musíš vykreslit sám (pokud na to neseženeš nějakou vypečenou komponentu). Grafické objekty reprezentuješ v paměti (... cokoliv plné objektů) a vykresluješ je v Paint. Pohyb myši nad takto vykreslenými objekty, klik do oblasti objektů a zvýraznění výběru objektů pak realizuješ změnou stavu jednotlivých objektů a tím i jejich vykreslení (jinak řečeno: je to podvod :smile1: ).

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
7. 4. 2010   #3
-
0
-

To liborb : mam plochu - pouzil som komponentu panel, a chcel by som ze ked na ten panel kliknem tak sa oznaci (obkresli sa ciarou s kotevnymi bodmi).... neviem prave ako vytvorit to oznacenie. postupne by som chcel pridat ze klik na ten kotevny bod a tah zmeni velkost toho panela.... len neviem ako sa na to pozerat...?

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
7. 4. 2010   #4
-
0
-

Myslíš něco podobného (nebo dokonce stejného) jako je v návrhu formuláře?

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
7. 4. 2010   #5
-
0
-

To liborb : nieco podobneho... skor sa to podoba na vlastnost ako ked vkladas textove pole... klikom nan ho oznacis a po okrajoch sa ti vykreslia take body, ktore ked uchopis a tahas tak menis velkost toho pola....

Nahlásit jako SPAM
IP: 158.196.47.–
liborb
~ Redaktor
+18
Guru
8. 4. 2010   #6
-
0
-

Vzhledem k tomu, že nevím, co s tím hodláš dále dělat, tak obecně tyto 2 možnosti:
- datový objekt reprezentovaný pomocí (jednoduché) grafiky a reakce na události od myši
- vytvořením vlastní komponenty, která bude dělat vlastně to samé

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
8. 4. 2010   #7
-
0
-

To liborb : chcem sa naucit pracovat s grafickymi objektami nic viac. ;) (mozeme sa bavit v teoretickej rovine)
to co si napisal 1 - dajme tomu ze nakreslim rectangle a kruh. a po kliknuti na kruh aby sa mi oznacil tak ako pisem by bolo treba urobit co? predpokladam ze .net asi nema fukciu ktora by ten select vykreslila ako je na obrazku...? chapem ze asi bude treba zistit rozmery a suradnice voci pozadiale neviem ako dalej ved aj na obraku ten select zasahuje do popredia aj do pozadia. a navyse chcem tieto kotevne body pouzit dalej, len som netusil ze to bude take drsne...

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
8. 4. 2010   #8
-
0
-

Není to zase tak drsné :smile1: .

Jde o to, že si musíš to, co vykreslíš nějak reprezentovat v paměti a nejlépe objektem. Nebo-li jinak, máš objekty v paměti a ty vykreslíš. Uděláš si třeba třídu MujObdelnik a ta budeme mit v sobě rozměry. Uděláš ji metodu na vykreslení (nebo si zadefinuješ rozhraní, to je pro začátek skoro jedno). V Paint pak zavoláš vykreslení. Následně budeš brát události od myši, zjišťovat, jestli je kurzor uvnitř toho objektu (další funkce), jestli si na objekt kliknul - vybral ho, jestli držíš tlačítko a pohybuješ myší, tj. pohybuješ objektem, jestli si v rohu, kde je "kotva" a tak změníš kurzor a povolíš změnu velikosti atd. atd.

Není to složité, jenom je potřeba vhodně ukládat vnitřní stavy objektů.

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
8. 4. 2010   #9
-
0
-

To liborb : to znie schodne ale porad netusim jak vykreslit ty kotevni body na oznaceny graficky objekt(jak je na tom obrazku). ked mam v pozadi panel a kliknem na picturebox(v popredi) , tak mozem kreslit bud na picturebox alebo na panel:



Graphics oznacenie = pictureBox1.CreateGraphics();

Pen pero = new Pen(Color.Blue,5);

oznacenie.DrawRectangle(pero, 0, 0, 5, 5);


ale nie pol na pol ako je to na tom obrazku.... dalo by sa to nejak ?

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
8. 4. 2010   #10
-
0
-

Pořád si asi úplně nerozumíme. Proč na tom panelu chceš použít PictureBox? Všechno můžeš vykreslit i na ten panel ...

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
8. 4. 2010   #11
-
0
-

To liborb : na tom pictureboxu si skusam to oznacenie a zmenu velkosti, panel pouzivam ako pozadie.... je snad uplne jedno ci oznaceny objekt bude rectangle, eclipse alebo picturebox... ci nie?

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
8. 4. 2010   #12
-
0
-

Tak úplně jedno to není. Obdélník jsou "namalované čáry", ale PB je ovládací prvek (okno se svým handle), který má svojí oblast, do které kreslí ....

Pokud chceš udělat ovládací prvek PB, který půjde vybrat a bude dělat všechno to, co si psal, tak to sis pro začátek vzal dost velké sousto (můj názor).

Pokud chceš vykreslit obdélník, který při kliknutí "do něj" něco udělá, půjde s ním pohybovat, bude mít kolem dokola kotvy na změnu velikosti .... tak zahoď PB a všechno kresli do toho panelu.

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
9. 4. 2010   #13
-
0
-

To liborb : ok tak teda to na zaciatok skusim so stvorcami.... mam triedu Obdelnik ktora ma svoje rozmery a metodu

  public void PaintObdelnik(Graphics gr) {...}


Je nejaky sposob ako to nakodit tak aby mi sam obdelnik vracal ze je na nom mys alebo musim vsetko hodit do udalosti formu, ktora zaznamenava click mysi (v tej udalosti zavolat metodu ktora skontroluje ci som klikol do obdlznika t.j. porovnat polohu+vyska,sirka obdelnika s polohou mysi)??

a potom ako teda s tym selectom toho stvorca?

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
9. 4. 2010   #14
-
0
-

Sám ti to neudělá, to by to právě musel být ovládací prvek.

Takže to opravdu musíš dát do události od formuláře. Začneme MouseMove ... tam dostaneš mimo jiné polohu kurzoru, kterou můžeš předat tomu svému objektu, aby ti řekl, jestli jsi uvnitř. Bude třeba vracet bool, a ten se ti bude hodit dále při kliku (výběru), takže si jeho hodnotu uložíš. Reakcí obdélníka (jeho vykreslení) může třeba být, že změníš barvu pera, když je kurzor uvnitř jeho oblasti.

A teď výběr ... to bude MouseDown ... z MouseMove víš, že jsi uvnitř obdélníka. Nebo-li pokud bude ten bool nahozený, tak můžeš zavolat další funkci toho svého obdélníka (třeba vyber), která změní stav obdélníka a ten zase upraví jeho vykreslení. Už se nebude vykreslovat jako prostý obdélník, ale řekněme, že mu v rozích uděláš plné čtverečky 5x5 pixelů nebo tak něco.

Samozřejmě je potřeba ošetřit plno věcí :smile1: , ale pro začátek stačí rozlišovat nad odbélníkem ano/ne a klik (když se to učíš). Jo a nezapomeň volat v MouseMove a MouseDown Invalidate (formuláře), aby se ti to překreslovalo. To taky pro začátek stačí (na double buffering je času dost).

Když tak sem vždycky šoupni aktuální výpis kódu, který zrovan máš ... pokud se ti teda bude chtít ... bude to tak pro všechny názornější.

Nahlásit jako SPAM
IP: 85.207.166.–
JardaJirava0
Stálý člen
9. 4. 2010   #15
-
0
-

Ahoj,
ber to jako můj názor, ale možná než začít hnedka "kodit" by bylo vhodnější se nad tím aspoň částečně zamyslet a rozvrhnout si, jak ta aplikace bude vypadat.
Pro začátek bych úplně ignoroval samotné vykreslování, na čem to bude ve výsledku zobrazeno.
Začal bych tedy nějakým Primitivem, což bude předek pro všechny objekty, které budou kresleny. Toto Primitivum pak bude mit virtualni (abstraktni) metody pro vykresleni, pro vraceni toho, zda dane souradnice obsahuje atd.
Dale bych si zalozil tridu, ktera bude kolekci pro tato Primitiva, rekneme PrimitiveContainer. Tato trida bude obsahovat seznam primitiv tak jak se pridavala a zaroven bude obsahovat dalsi metody, treba prohozeni Primitiv nebo otestovani souradnice, ktere Primitivum se prvni chyti a toto vrati a samozrejme i jejich zobrazeni.
Dale bych si vytvoril nejaky dekorator, ktery bude umet vykreslit nejen dane Primitivum, ale take uchycovaci body.
Samotnou implementaci metod bych neresil a klidne si jen psal Debug.Writeline("vypisuji obdelnik na pozici x1,x2 az y1,y2") atd. Az si budes myslet, ze vsechno tohle je funkcni a dokazes tim nasimulovat pozadovane chovani aplikace, tak muzes zacit resit samotne vykreslovani a uvidis, ze razem ti to zacne vse pekne zapadat. Kazde odvozene primitivum pak samozrejme bude mit vlastni vlastnosti, podle kterych se bude ridit zobrazovani.
Co ti potom bude stacit. Nekde v tvem prvku, ktery bude obsahovat jeden panel nebo PictureBox nebo cokoliv od techto odvozenych na co se da kreslit instancovat PrimitiveContainer (PC) a postupne do nej pridavat jednotliva konkretni Primitiva. V metode OnPaint pak projit PrimitiveContainer a pozadat jej o vykresleni obsazenych prvku.
Dale si pak osetris treba kliknuti mysi, zjistis si souradnice a predas je PC ten ti vrati nejake Primitivum, a toto predas do Dekoratoru, ktery se postara o odekorovani. Samozrejme muzes jit i dale a mit v PC seznam vybranych prvku (muze jich byt vice) a ty se budou vykreslovat za pomoci dekoratoru.
Operace v samotne UI vrstve tak budou velice jednoduche a vse bude zalezitost PC pripadne daneho Primitiva.

Pekny den,

Jarda Jirava

Nahlásit jako SPAM
IP: 194.213.35.–
MCAD, MCPD
http://jirava.net/blog
http://xaml.cz - Magazín moderních technologií založených na XAML
Misiak0
Návštěvník
9. 4. 2010   #16
-
0
-

To liborb : :) kod klidne odhalim. asi som niekde urobil chybu co sa tyka logiky zmeny farby ctverca... takze bych bol rad za pripomienky :) (formular ma toolstrip tlacitko ktore ked je stlacene tak sa po kliku na panel vykresli obdelnik zelenej farby metodou PaintObdelnik() ked je mys v obdelniku tak sa zavola metoda Change_color() )



namespace kreslitko
{
public partial class Form1 : Form
{
private Graphics grafika;
private int oldx, oldy;
private bool pouzi = false;
private bool drzklik = false;
private List<Obdelnik> lobdelnik = new List<Obdelnik>();

public Form1()
{
InitializeComponent();
splitContainer1.Panel1.BackColor = Color.Silver;
panel1.BackColor = Color.White;
panel1.MouseDown += new MouseEventHandler(Moj_klikdole);
panel1.MouseUp += new MouseEventHandler(Moj_klikhore);
panel1.MouseMove += new MouseEventHandler(Poloha_kurzora);
}

private void Moj_klikdole(object sender, MouseEventArgs e)
{
oldx = e.X;
oldy = e.Y;
drzklik = true;

if (btnRec.Checked)
{
Obdelnik obdelnik = new Obdelnik();
grafika = panel1.CreateGraphics();
obdelnik.PaintObdelnik(grafika);
lobdelnik.Add(obdelnik);
}
}

private void Moj_klikhore(object sender, MouseEventArgs e)
{
drzklik = false;
}


private void Poloha_kurzora(object sender, MouseEventArgs e)
{

label1.Text = "[ " + e.X + " , " + e.Y + " ]";
if (lobdelnik.Count > 0)
{
pouzi = lobdelnik[0].PolohaTelese(e.X, e.Y);
if (pouzi)
{
lobdelnik[0].Change_color(grafika);
}
else {
lobdelnik[0].PaintObdelnik(grafika);
}
}
}

private void btnRec_Click(object sender, EventArgs e)
{
if (!btnRec.Checked)
{
btnRec.Checked = true;
}
else {
btnRec.Checked = false;
}
}

private void toolStripButton1_Click(object sender, EventArgs e)
{
if (!btnSel.Checked)
{
btnSel.Checked = true;
}
else {
btnSel.Checked = false;
}
}
}
}




a teraz trieda Obdelnik



namespace kreslitko
{
class Obdelnik
{

private int topx;
private int topy;
private int width;
private int height;


public Obdelnik(int x, int y, int owidth, int oheight) {

topx = x;
topy = y;
width = owidth;
height = oheight;

}

public Obdelnik()
{
SGetLokacionX = 20;
SGetLokacionY = 20;
SGetWidth = 40;
SGetHeight = 40;
}

public int SGetLokacionX {

set { topx = value; }
get { return topx; }

}

public int SGetLokacionY
{

set { topy = value; }
get { return topy; }

}
public int SGetWidth
{

set { width = value; }
get { return width; }

}

public int SGetHeight
{

set { height = value; }
get { return height; }

}


public void PaintObdelnik(Graphics gr) {

Pen pero = new Pen(Color.Green, 4);
gr.DrawRectangle(pero, this.topx,this.topy,this.width,this.height);
}

public bool PolohaTelese(int x, int y) {
bool ano = false;


if (x >= SGetLokacionX && x <= (SGetLokacionX + SGetWidth))
{
if (y>= SGetLokacionY && y <= (SGetLokacionY + SGetHeight))
{

ano = true;
}
}

return ano;

}


public void Change_color(Graphics gr)
{
Pen pero = new Pen(Color.Red, 4);
gr.DrawRectangle(pero, this.topx, this.topy, this.width, this.height);
}
}
}


teraz nechapem ako si myslel to oznacenie - Nova trieda - ktora bude generovat nejake Controls 5x5px co sa vykreslia na urcitych bodoch stvorca? alebo si myslel nejake nove cerne ctverecky ci nejake body 5x5 co sa nakreslia na rohy stvorca (tym ze ziskam rozmery stvorca....? )a zase som u problemu maly cerny ctverecek (pretoze som ho chcel vykreslit polka "kotvy" na obdelniku a polka mimo) klik na "kotvu" a zmena velkosti Obdelnika (prekreslovanie)...

PS: sorry za take vypisovanie ale velmi ma to zaujima...

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
9. 4. 2010   #17
-
0
-

To je v pořádku, že tě to zajímá ... takže není za co se omlouvat. Každý nějak začínal, málokdo se rodí s dokonalou znalostí OOA :smile1: .

A teď ty připomínky. S tou změnou barvy ti to nemůže fungovat úplně správně, protože si musíš uvědomit jednu věc. ChangeColor voláš "jen" při pohybu myší, ale PaintObdelnik se volá i v jiných případech. Nebo-li je potřeba do toho obdélníka uložit, že měníš jeho barvu (stav), ale vykreslení ponechat pouze jenom v PaintObdelnik (a to platí (až do odvolání :smile1: ) i pro další situace, které nastanou). Takže by to mohlo vypadat nějak takto:




public void Change_color(Color color)
{
barva = color;
}

public void PaintObdelnik(Graphics gr)
{
Pen pero = new Pen(barva, 4);

gr.DrawRectangle(pero, this.topx,this.topy,this.width,this.height);
}



A sazmozřejmě v konstruktoru nastavíš výchozí barvu na zelenou.


Pak dál ... vykresluješ obdélník při pohybu myší ... měl by si ho vykreslovat spíš v Paint toho Panelu a v reakci na myš jen měnit stav (barvu obdélníka). jde totiž o to, že pak až toho bude víc, tak neustálé překreslování všeho je nesmysl. Následně by se detekovala změna a volalo se Invalidate ... teď se na tohle můžeš vybodnout a volat Invalidate stále, ale to umístění vykreslení do reakce na pohyb myši je dost nešťastné a vlastně i trochu omezující.


A pak dál ten výběr a čtverečky :smile1: . No ... ty přece nejsi omezen plochou vymezenou obdélníkem, ale tím Panelem. Takže můžeš udělát něco takového:

public void PaintObdelnik(Graphics gr)
{
Pen pero = new Pen(barva, 4);

gr.DrawRectangle(pero, this.topx,this.topy,this.width,this.height);

if (vybran)
{
// vykresleni kotev i za hranice obdelnika
}
}


BTW základem té třídy obdélníka mohl být Rectangle (obdelnik) a pak jsou některé věci snadnější:



public bool PolohaTelese(int x, int y)
{
return(obdelnik.Contains(x, y));
}

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
12. 4. 2010   #18
-
0
-

To JardaJirava : to mas recht ze sa treba zamysliet ako bude cela aplikacka vypadat, ale najskor aby som mohol napisat vykreslovanie , tak musim pochopit ako vykreslovat, na ake platno, aku vrstvu ako oznacit ako robit body , krivky a jejich selekciu... ked budem chciet postavit celu aplikaciu tak sa budem snazit to nejak dat dokopy ako hovoris.... ;)

Nahlásit jako SPAM
IP: 89.24.189.–
Misiak0
Návštěvník
12. 4. 2010   #19
-
0
-

To liborb : vedel som ze mi cosi nesedi... :) no tu zmenu farby som prepisal ako si spominal a prepisal som aj vykreslovanie do paint toho panelu ale teraz sa mi ten stvorec vobec nevykresli.... ked necham paint v kliku na platno tak mi zas nemeni farbu.... pripajam zdrojak



namespace kreslitko
{
public partial class Form1 : Form
{

private Graphics grafika;
private int oldx, oldy;
private bool pouzi = false;
private bool drzklik = false;
private List<Obdelnik> lobdelnik = new List<Obdelnik>();

public Form1()
{
InitializeComponent();
splitContainer1.Panel1.BackColor = Color.Silver;
panel1.BackColor = Color.White;
panel1.Paint += new PaintEventHandler(MujPaintEventHandler);
panel1.MouseDown += new MouseEventHandler(Moj_klikdole);
panel1.MouseUp += new MouseEventHandler(Moj_klikhore);
panel1.MouseMove += new MouseEventHandler(Poloha_kurzora);

}




private void Moj_klikdole(object sender, MouseEventArgs e)
{
oldx = e.X;
oldy = e.Y;
drzklik = true;

}

private void Moj_klikhore(object sender, MouseEventArgs e)
{
drzklik = false;
}

private void MujPaintEventHandler(object sender, EventArgs e)
{

if (btnRec.Checked)
{
Obdelnik obdelnik = new Obdelnik();
grafika = panel1.CreateGraphics();
obdelnik.PaintObdelnik(grafika);
lobdelnik.Add(obdelnik);
}
}


private void Poloha_kurzora(object sender, MouseEventArgs e)
{

label1.Text = "[ " + e.X + " , " + e.Y + " ]";
if (lobdelnik.Count > 0)
{
pouzi = lobdelnik[0].PolohaTelese(e.X, e.Y);
if (pouzi)
{
lobdelnik[0].Change_color(Color.Red);

}
}

}


private void btnRec_Click(object sender, EventArgs e)
{
if (!btnRec.Checked)
{
btnRec.Checked = true;
}
else {
btnRec.Checked = false;
}
}
}
}
a trieda Obdelnik




private Rectangle obdlznik;
private Color farba;

public Obdelnik()
{
SGetLokacionX = 20;
SGetLokacionY = 20;
SGetWidth = 40;
SGetHeight = 40;
farba = Color.Green;
obdlznik = new Rectangle(SGetLokacionX, SGetLokacionY, SGetWidth, SGetHeight);
}

public void PaintObdelnik(Graphics gr) {

Pen pero = new Pen(farba, 4);
gr.DrawRectangle(pero, obdlznik );
}

public void Change_color(Color f)
{
farba = f;
}




takze chyba je vo vykresleni, v detekcii zmeny a prekresleni :(

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
12. 4. 2010   #20
-
0
-

Je to trochu divoké, hlavně vznik toho Obdelnika.

Pro zachování své i mojí duševní svěžesti :smile1: udělej tyto drobné změny:
- checkboxy nahraď jedním buttonem, do jeho události po kliknutí dej tento kód (vložení Obdelnik do seznamu):



Obdelnik obdelnik = new Obdelnik();

lobdelnik.Add(obdelnik);


- následně je potřeba změnit Paint, aby se volalo vykreslení obdelníků z listu (něco jako):


foreach (Obdelnik x in lobdelnik)
{
x.PaintObdelnik(grafika);
}


- atribut grafika si tam někde jednorázově inicializuj, když si ho udělal členskou proměnou

- a na konec události od pohybu kurzoru dej (prozatím) panel1.Invalidate();

No a aby se ti měnila barva tam i zpět, tak pokud detekuješ, že není kurzor v oblasti dané odbélníkem, tak ji nastav zase zpět. Případně si to může obdélník obsluhovat sám v PolohaTelese.

Nahlásit jako SPAM
IP: 85.207.166.–
JardaJirava0
Stálý člen
12. 4. 2010   #21
-
0
-

Ahoj, tak a pomalu se liborb dostava k tomu, co jsem popisoval. To nemyslim nijak zle, je to o tom, ze driv nez zacnes neco kreslit, zkus si postavit ten zaklad. Ono je vzdy lepsi mit papir a tuzku a pak s nimi zacit kreslit :-) nez zacit rovnou kreslit, pak vetsinou zjistis, ze neco potrebujes nekde jinak a ze mas vse silene provazane a ze se ti to nepodari jen tak roztrhnout. Takze se vlastne pak znovu ucis kreslit.

Pěkný den,

Jarda Jirava

Nahlásit jako SPAM
IP: 194.213.35.–
MCAD, MCPD
http://jirava.net/blog
http://xaml.cz - Magazín moderních technologií založených na XAML
liborb
~ Redaktor
+18
Guru
14. 4. 2010   #22
-
0
-

To JardaJirava : Samozřejmě, že máš pravdu. Měl si ji i před tím. A budeš ji mít v podstatě kdykoliv, kdy podobný příspěvek vložíš téměř do jakéhokoliv vlákna. Pořádně si to rozmyslet a pak teprve kódovat. Problém je o všem v tom, že ten dotyčný musí vědět CO chce resp. musí mít alespoň minimální ánunk o tom, jak dosáhnout cíle. Na jednoduchém prototypu není nic špatného. Když neví, co od dané problematiky může očekávat, tak je to (dle mého skromného praxí podloženého názoru) nejlepší cesta.

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
14. 4. 2010   #23
-
0
-

To liborb : jj oka, prehodil som tvorbu toho obdlznika do zmacknutia toolstripbuttonu (ma vlastnost checked) takze novy obdlznik hodim do zoznamu,ale... no radsej hodim kod





private Graphics grafika;


public Form1()
{

InitializeComponent();
...
panel1.Paint += new PaintEventHandler(MujPaintEventHandler);
....

}

private void MujPaintEventHandler(object sender, PaintEventArgs e)
{

if (lobdelnik.Count > 0)
{
grafika= panel1.CreateGraphics();
foreach (Obdelnik ob in lobdelnik)
{
ob.PaintObdelnik(grafika);

}
}

}
}


nic to nevykresli , takze mi nie je uplne jasne preco sa hodi vykreslovanie stvorca do udalosti Paint panela(pretoze paint panela sa zavola len pri tvorbe ). skusil som grafiku extrahovat z prichadzajuceho e (e.Graphics ),ale nefunguje.preto som si ani neni uplne isty inicializaciou tej grafiky(grafika= panel1.CreateGraphics(); )

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
14. 4. 2010   #24
-
0
-

Proměná grafika je členská, takže ji stačí nastavit jen poprvé:



if (grafika == null) grafika = panel1.CreateGraphics();


a následně (jestli to tam nemáš) nakonec zpracování pohybu myši (Poloha_kurzora) vlož:



panel1.Invalidate();


to způsobí, že se panel1 bude překreslovat nejenom při vytvoření a obnovení, ale vlastně stále. Není to sice moc správně, ale v tuto chvíli je to naprosto jedno.

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
13. 5. 2010   #25
-
0
-

To liborb : super funguje to a aj som sa nieco naucil... , po dlhsej odmlke sa k tomu vraciam, teraz by ma zaujimalo vykreslenie toho oznacenia dookola. napadlo ma spravit si triedu co bude vykreslovat po obvode akehokolvek telesa 6 ciernych stvorcekov (a tym oznacit objekt za selektnuty:) - cize sa s nim bude dat napr. posuvat ) ale netusim ako ich vykreslit aby boli polovicne na objekte a polovicne mimo, alebo sa to neda?

dik

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
14. 5. 2010   #26
-
0
-

Samozřejmě se to dá. Jak jsem psal někdy výše, nejsi omezen oblastí danou rozměry obdélníka, ale můžeš jít i za ni, např.:



if (vybran)
{
using (SolidBrush stetec = new SolidBrush(barva))
{
gr.FillRectangle(stetec, obdlznik.Left - 3, obdlznik.Top - 3, 6, 6);
gr.FillRectangle(stetec, obdlznik.Right - 3, obdlznik.Top - 3, 6, 6);
gr.FillRectangle(stetec, obdlznik.Left - 3, obdlznik.Bottom - 3, 6, 6);
gr.FillRectangle(stetec, obdlznik.Right - 3, obdlznik.Bottom - 3, 6, 6);
}
}


Tento kód by byl v PaintObdelnik. Ve chvíli, kdy by si vybral jeden obdélník, tak by si nahodil flag vybran (boolovskou proměnnou) a následně se vykreslí tyto kotevní body v rozích.

A teď k tomu kde to vykreslovat. Řekl bych, že jsou 2 možnosti. Buď budou kotevní body odpovídat tvaru grafického objektu (obdélník, kruh, trojúhelník ...) - jejich poloha a počet bude tvar od tvaru jiný. V tomto případě to musí mít na starosti příslušná třída (Obdelnik, Kruh, Trojuhelnik ...).

Druhá možnost je možná častější. Každý tvar lze opsat obdélníkem, který vymezuje oblast, ve které se daný tvar nachází. Takže se vytvoří základní třída (GrafickyObjekt), která bude vykreslovat společné věci dané tímto obdélníkem. Např. právě ty kotevní body po obvodu obdélníka, naznačení výběru tvaru apod. Zděděné třídy Kruh, Obdelnik, Trojuhelnik musí "pouze" správně určovat rozměry tohoto opsaného obdélníku.

Když tak se zase hoď kompletní kód, aby nedošlo k nějakému nedorozumění a samozřejmě i pro zvědavce :smile1: .

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
18. 5. 2010   #27
-
0
-

To liborb : ted mozna taka blba otazka ale nerozumiem preco si pouzil blok

 using( ){ } 
ja myslel ze sa tym nacitaju len nejake namespace a kniznice...

- flag vybran by si nastavil jako "public bool vybran..." by si dal ako clensku premennu triedy Obdelnik alebo ju do vlastnej triedy nastavil ako samostatnu staticku premennu, alebo radej ako vlastnost triedy Obdelnik ?

no a nastava problem s prekreslenim pretoze ked dam kod na vykreslenie stvorcekov do udalosti zmacknute tlacitko tak vsetko ok, pokial tlacitko drzim, ked ho ale pustim cary mary fuk stverecky zmiznu, takze panel1.invalidate()... treba zavolat len pri nejakej zmene na platne vsak? to jest - hodit prekreslenie do nejakej osobitnej funkcie ktora sa potom bude volat po kazdej zmene na platne [ako je vykreslenie obdlznika, zmena farby, vykreslenie stvorcekov...atd] je to spravna cesta ci je aj iny sposob?

Nahlásit jako SPAM
IP: 89.24.189.–
liborb
~ Redaktor
+18
Guru
18. 5. 2010   #28
-
0
-

Zjednodušeně řečeno ... using (něco) vlastně značí, že to něco chceš používat jen pro tento kousek kódu. Na pozadí jsou takové drobnosti ohledně bloku try/finally a bezpečného uvolnění alokovaných zdrojů atd. atd.

Flag bych jako public určitě nenastavil. Je to vnitřní atribut objektu. Stav, který si musí objekt spravovat sám. Dal bych ji jako členskou proměnnou třídy Obdelnik (private) případně jako členskou proměnnou třídy GrafickyObject (protected), od které bude Obdelnik dědit.

A k tomu poslednímu ... dej se, prosím tě, kód. V popisu už se bohužel ztrácím. Ale jinak musíš překreslit celé plátno (nebo jeho část) při každé změně, která způsobila změnu obsahu plátna. A samozřejmě ho musíš vykreslit i v případě, že vykreslení požadauje systém.

Nahlásit jako SPAM
IP: 85.207.166.–
Misiak0
Návštěvník
28. 6. 2010   #29
-
0
-

To liborb : len co sa k tomu znovu dostanem aby som to prerobil hodim sem kod...

Nahlásit jako SPAM
IP: 89.24.189.–
mat00
~ Anonymní uživatel
1 příspěvek
25. 4. 2011   #30
-
0
-

Ahojte, ja by som mal tiez otazku. Mam za ulohu vyplnanie pravouhlej oblasti(obdlznika) semienkovym riadkovym algoritmom. S cim si neviem rady, to je vykreslenie toho obdlznika. TU je moj kod:

using System;

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

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Bitmap pozadie;







public Form1()
{
InitializeComponent();


}
System.Drawing.Rectangle obdlznik = new Rectangle( );



private void Program(object sender, EventArgs e)
{
pozadie = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics GFX = Graphics.FromImage(pozadie);

}

private void Bod_X_TextChanged(object sender, EventArgs e)
{

}

private void Bod_Y_TextChanged(object sender, EventArgs e)
{

}

private void Bod_A_TextChanged(object sender, EventArgs e)
{

}

private void Bod_B_TextChanged(object sender, EventArgs e)
{

}



private void Rozmery(object sender, EventArgs e)
{

if (Bod_A.Text != string.Empty && Bod_B.Text != string.Empty)
{
int a;
int b;
a = Convert.ToInt32(Bod_A.Text);
b = Convert.ToInt32(Bod_B.Text);
Size s = new Size(a, b);
obdlznik.Size = s;
MessageBox.Show("Rozmery boli nastavene.");

}
else
MessageBox.Show("Zadajte prosim hodnoty.");

}




private void pictureBox1_Click(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Right:
{
Size s = new Size();
s = obdlznik.Size;
Point p = new Point();
p = obdlznik.Location;
Graphics GFX = this.pictureBox1.CreateGraphics();
Pen pero = new Pen(System.Drawing.Color.Black, 1f);
Rectangle rect = new Rectangle(p,s);
GFX.DrawRectangle(pero, rect);
Size d = new Size();
d = obdlznik.Size;
MessageBox.Show("current size \n" + "Height:" + s.Height.ToString() + "Width:" + s.Width.ToString());
}
break;
case MouseButtons.Left:
{
int x = 0;
int y = 0;
x = Cursor.Position.X;
y = Cursor.Position.Y;
Point p = new Point(x, y);
obdlznik.Location = p;
MessageBox.Show("Pociatocny bod bol nastaveny.");
}
break;

}
}


}
}


Je to este len velmi zaciatocny kod. Neviem si rady konkretne s tymto: System.Drawing.Rectangle obdlznik = new Rectangle( );
Vstupne hodnoty sa maju zadavat cez Textbox. Ked do zatvorky zapisem hodnoty, tak mi to vykresli obdlznik, ale ked sa pokusam hodnoty ziskat z Textboxu, tak mi nic nepriradi. Vedel by mi niekto pomoct? Pripadne nejaky jednoduchejsi sposob ziskania rozmerov obdlznika? DAkujem vopred

Nahlásit jako SPAM
IP: 87.244.196.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 15 hostů

Podobná vlákna

Objekty — založil zmetek

Objekty — založil Miro1701

Objekty — založil allicce

Objekty — založil Onsi

Struktury a objekty — založil Bobek6

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý