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
Fórum › .NET
Graficke objekty c#
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: ).
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...?
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é
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...
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ů.
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 ?
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.
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?
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ší.
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
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...
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));
}
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.... ;)
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 :(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.
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
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.
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(); ) 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.
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
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: .
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?
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.
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
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze