C#, Textbox, OnPaint metódus probléma


 Sziasztok!
A problémám a következő :
Van egy osztályom, melynek a neve MyTextbox, melyet a Textbox osztályból származtattam.
A gondok akkor jöttek mikor bele szerettem volna vinni a MyTextbox-ba extra dolgokat, és sajnálattal tapasztaltam, hogy a Textbox-nak nincs Paint event-je.
Igaz van egy OnPaint metódusa amit felül lehet definiálni, ami mellesleg először le se akart nekem futni. Aztán utánanéztem neten, és kiderült, hogy a MyTextbox konstruktorába be kell írni a következő utasítást :
this.SetStyle(ControlStyles.UserPaint, true);
Hát így már valóban lefutott, de kb. semmire nem mentem vele, mert pl. teljesen más Fonttal írta ki amit akartam, kicsit érdekesen működött.
Szóval a kérdésem az lenne, hogy hogyan lehetne megoldani azt, hogy a MyTextbox osztály ki tudjon rajzolni plusz dolgokat? |
És milyen Texboxod van? Van belőle egy pár fajta.
Van Textboxa a:
- windows[.forms]
- TextBoxBase (szintén windows]
- Web.UI.WebControls.TextBox
- És bár én nem használom de gondolom van textbox a:
- WPF-ben
- SilverLightban
Van valami amit kihagytam?
Amúgy desktopon Paint metódus van tudtommal, weben Render.
Morzel |
Egészen pontosan ilyet használok :
System.Windows.Forms.TextBox; |
Nagyjából ennyit találtam. A lényeg, hogy új kontrollt hoz létre és annak minden vackát megadja. Olyan használható példát nem igazán találtam hogy Textboxból származtatsz és annak felülírod az OnPaintjét, bár elvileg szerintem mennie kellene (Csak akkor arra kell vigyázni szerintem hogy ne akadjon össze semmivel hogy ne hívd meg a végén a base.Paint()-et mert akkor mindkettő lefut elvileg. Még nem próbáltam soha, egy pár percet szerintem megér.
Amúgy én weben próbálkoztam hasonlóval és az a tapasztalatom hogy ha van adatkötés meg kapcsolat a kontrollok között akkor meglepetést okozhat a default kinézet teljes felülírása... Mondjuk weben még odajönnek a javascriptek is tömkelegestül és azok igazán szép dolgokat tudnak tenni ha egy input type=text helyett egy span-t találnak...
Morzel |
Köszönöm a segítséget!
Amúgy közben megoldódott a probléma. :)
Annyi az egész, hogy csináltam magam egy Paint eseménykezelőt, ami akkor fut le, amikor szeretném, és már kész is.
Igazából nemtom mért nem jutott először eszembe ez a megoldás.
Mondjuk mikor neten utánanéztem ennek, mindenki arra panaszkodott, hogy hát mennyire nem jó ez az OnPaint metódus, meg mindenféle hülye megoldást mutattak, amit ugye le se teszteltek.
Na mind1, a lényeg, hogy probléma megoldva... :) |
Annyi az egész, hogy csináltam magam egy Paint eseménykezelőt
Bocsi, de a kódját közreadnád?
Tán még pontot is kapnál érte (ha elfogadod).. |
Hogy majdan nevén nevezzük ezt a gyereket, a két aspektus, ami feljött megoldásként a következő:
A textboxból való származtatás: Subclassing
A textbox onPaint eventjére való ráakaszkodás: Helper method és observer pattern
És egy brief description a kettőről:
Once upon a time (before Baywatch), there was a man with no name.
Knight Industries decided that if this man were given guns and wheels
and booster rockets, he would be the perfect crime-fighting tool.
First, they thought, "Let's subclass him and override everything we
need to add the guns and wheels and booster rockets." The problem was
that to subclass Michael Knight, you would need to know an awful lot
about his guts so that you could wire them to guns and booster
rockets. So instead, they created a helper object, the Knight
Industries 2000, or "KITT the super car."
Note how this is different from the RoboCop approach. RoboCop was a
man subclassed and extended. The whole RoboCop project involved dozens
of surgeons who extended the man's brain into a fighting machine. This
is the approach taken with many object-oriented frameworks.
|
1000 bocsánat, hogy nem válaszoltam eddig... :)
Na szal az egész kódot, inkább nem szúrom be, de a lényeg ittvan
:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Program
{
public class MyTextBox : TextBox
{
public event PaintEventHandler Paint;
public MyTextBox() : base()
{
...
this.Paint += new PaintEventHandler(Painting);
this.MouseClick += new MouseEventHandler(MouseClick);
...
}
/* Gombnyomásra kirajzolunk vmi extra dolgot */
protected void MouseClick(object sender, MouseEventArgs e)
{
this.Paint(this, new PaintEventArgs(this.CreateGraphics(), new Rectangle(this.Location.X, this.Location.Y, this.Size.Width, this.Size.Height)));
}
/* És itt rajzolhatunk */
private void Painting(object sender, PaintEventArgs e)
{
this.refresh(); // Először kirajzoltatjuk az eredeti TextBox-ot
e.Graphics.DrawLine(...)
...
}
}
}
Na és ennyi az egész.
Megjegyezném, hogy ilyen függvény hívást, hogy this.Paint(...) csak ebben az osztályban (MyTextBox) lehet kiadni.
Ha a MyTextBox-ból ismét származtatunk egy osztályt, és szeretnénk az ősosztályban lévő Paint használni, felűldefiniálni, stb., akkor pedig a következőképp kell eljárni :
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Program
{
public class MyTextBox : TextBox
{
protected event PaintEventHandler Paint;
public MyTextBox() : base()
{
... ...
}
public void Repaint()
{
this.Paint(this, new PaintEventArgs(this.CreateGraphics(), new Rectangle(this.Location.X, this.Location.Y, this.Size.Width, this.Size.Height)));
}
protected virtual void Painting(object sender, PaintEventArgs e) { }
}
}
Így rábízhatjuk a Painting definiálását a gyerekre, de nyilván az ősben is definiálhatjuk. Ha ekkor meg szeretnénk hívni a Painting metódust, csak ki kell adnunk a Repaint() függvényhívást.
Asszem ennyi... :) |
|