Dědění   zodpovězená otázka

VB.NET, WinForms

Zdravím,

vytvářím vlastní komponentu, kterou jsem založil na RichTextBox (tím myslím, že ho dědí). No a mne by zajímalo, jestli můžu některé vlastnosti a metody RichTextBoxu skrýt. Zatím jsem to udělal tak, že přetěžuji zmíněné metody s tím, že jsem je udělal ReadOnly a vrací defaultní hodnotu, atributem <Browsable("False")> _ je pak skryl v PropertyGridu. Ovšem když je přetížím jako Public členy, jsou sice RO ale pořád viditelné a když zvolím jiný kontext, nejsou z jiných tříd vidět ty přetížené varianty, ovšem ty původní přístupné jsou. Nevíte co s tím? Resp. jdou ty vlastnosti skýt?

Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Skrýt členy základní třídy v odvozené třídě lze pomocí techniky zvané Shadowing.

Public Class A
  Private n As Integer = 123
  Public Property Number() As Integer
    Get
      Return n
    End Get
    Set(ByVal value As Integer)
      n = value
    End Set
  End Property
End Class

Public Class B
  Inherits A
  Private Shadows Property Number() As Integer
    Get
      Return 456
    End Get
    Set(ByVal value As Integer)
    End Set
  End Property
End Class

Bohužel vlastnost Number je stále dostupná v kódu a skryje se pouze v Object Browseru, čehož jsem si původně nevšiml, omlouvám se. Jiná technika kromě Overrides nebo Shadows neexistuje.

Pokud použijete Shadowing a budete pracovat s vlastností Number u proměnné typu B, budete ve skutečnosti pracovat s vlastností Number základní třídy A.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Perfektní, moc jste mi pomohl. Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Použil jsem Váš kód, přímo ten Váš a někde je asi chyba. Vlastnost je pořád viditelná.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ještě bych poznamenal, že jestliže vytváříte vlastní komponentu a vadí vám velké množství zděděných vlastností (u třídy odvozené od Control je to přes 100 veřejných členů) je vhodné implementovat návrhový vzor Facade.

Vytvoříte si rozhraní, které bude obsahovat pouze vámi požadované členy a toto rozhraní pak implementujete danou komponentou. Kdekoliv pak budete pracovat s komponentou, použijete proměnnou typu toho rozhraní a uvidíte pouze členy které chcete, ne všechno co patří do třídy Control.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Přečetl jsem si pár článků o Façade, ale obávám se, že z toho nejsem moc chytrý. Mohl bych poprosit o ukázku implementace toho návrhového vzoru? Děkuji.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Základní použití vzoru Facade je velmi jednoduché:

'Definice rozhraní (fasády - Facade) pro ovládání komponenty
Public Interface IColorizerControls
  Property Content() As String
  Property HighlightingEnabled() As Boolean
End Interface

Public Class Colorizer
  Inherits Control
  'Implementace rozhraní
  Implements IColorizerControls
  Public Property Content() As String Implements IColorizerControls.Content
    Get
      Return ...
    End Get
    Set (ByVal value As String)
      ...
    End Set
  End Property
  Public Property HighlightingEnabled() As Boolean Implements IColorizerControls.HighlightingEnabled
    Get
      Return ...
    End Get
    Set (ByVal value As Boolean)
      ...
    End Set
  End Property
End Class

'Použití:
Dim colorizer1 As IColorizerControls = New Colorizer()
colorizer1.Content = "<html></html>"
'Protože pracujete s rozhraním IColorizerControls, které
'je implementováno třídou Colorizer, budete mít k dispozici
'pouze vlastnosti které vás zajímají, nikoliv všechno
'co obsahuje třída Control ze které je Colorizer odvozen.

Zjednodušeně řečeno vám ta fasáda zprostředkovává pouze ty věci, které potřebujete.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Skvělé, to je pro mne naprosto ideální řešení. Děkuji.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle není přímo k tématu, ale jestli se takhle snažíš psát tu komponentu pro obarvování syntaxe, tak nevím, jestli RichTextBox je ideální model, ze kterého bys měl dědit. Dědičností spíš rozšiřuješ to, co třída umí, a přidáváš k ní věci, případně je trochu měníš. Rušit funkcionalitu něčeho děděním není příliš praktické. Vlastnost skrýt jít ani nemůže, to by pak popíralo dědičnost a polymorfismus.

Nejlepší by fakt bylo asi začít tím, že si podědíš třídu Control, a naprosto všechno si budeš vykreslovat sám. Ta třída nebude umět o nic víc, než má, kódem si do ní vygeneruješ dva scrollBary podle nastavení nějaké vlastnosti a v Paintu budeš překreslovat to, co je aktuálně vidět. Jednotlivé řádky textu si můžeš pamatovat v nějakém List(Of String), dobře se do něj přidává a maže, atd. No a pak už zbývá jenom klikání, chytání kláves a reakce na ně, je toho hodně.

Ještě jsem v .NETu viděl třídu TextBoxBase, nevím, co umí, ale možná by to byl lepší předek pro dědění, přeci jen psát si sám úplně všechno taky není nejlepší. Ale fakt nevím, co ta třída umí. Nebo si v ObjectBrowseru zjisti, z čeho dědí TextBox a co by se ti hodilo. Dědičností odebírat vlastnosti nejdou, můžeš je jenom skrýt pro design režim, ale to není dobrá cesta. Lepší je přidávat než ubírat.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ano, máš pravdu, je to způsob jakým se snažím vytvořit ten colorizer. Zatím jsem si navrhl i komponentu, kterou vykresluji sám, ale přišlo mi zajímavé, jak snadno se dá obarvovat RTB, tak jsem si řekl, že by nemuselo být marné zkusit to i tak. Na netu jsem kdysi našel třídu, jež si brala v konstruktoru jako parametr RTB a pak jej taky obarvovala, ale nedědila z něj. Fungoalo to perfektně, ale bylo založeno na WIN API a já se teď snažím napsat stejnou třídu s tím, že bude z RTB dědit. Zatím to celkem jde, takže si nemyslím, že bych to měl uzavírat. Ty vlastnosti navíc mi tam vcelku nevadí, šlo mi jen o to, že je nepoužívám ani u RTB, takže mi přišli zbytečné u CodeBoxu (jak jsem svou komponentu pojmenoval).

A ještě, ať nezakládám zbytečně nové vlákno, bych měl dotaz k RegExům:

        For Each Word As String In Me.Keywords
            For Each match As Match In Regex.Matches(Me.Text, "(?<=[\s|(|)|.])" & Word.ToLower & "(?=[\s|(|)|.])\b", RegexOptions.IgnoreCase)
                Me.SelectionStart = match.Index
                Me.SelectionLength = match.Length
                Me.SelectionColor = Me.ForeKeywordColor
            Next
        Next

Kde KeyWords je pole řetězců reprezentující klíčová slova jazyka (hodlám to rozšířit na několik sad slov, přičemž každá by měla jinou barvu, což je v některých jazycích třeba). Tento RV mi sice označí všechna klíčová slova, ale nikdy neoznačí slovo, které je na úplném začátku textu. Nevíte proč?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nevím, jestli ten RegExp chápu správně, nevím, co to má dělat, ale patrně jsi zapomněl dát backslash před tečku. Tečka má v RegExpu význam libovolného znaku, což asi není to, co potřebuješ.

Místo tečky dej \. a mohlo by to chodit, on totiž jinak před slovem očekává libovolný znak. Anebo se pletu. Btw co dělá pls \s, ať to nemusím hledat, nikdy jsem to nepoužil a rád bych věděl, na co to je.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

\s je whitespace.

a RegEx už chodí. Měl jsem nastavené, že se klíčová slova napsala korektně, pokud byla napsána malými písmeny a proto tam byly takové hacky jako ošetřování, jestli je klíčové slovo u závorky a tak. Teď jsem nalezl jiné řešení a RegEx upravil takto: "\b" & word & "\b", docela rozdíl. :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No, \b je začátek nebo konec slova, to by dávalo smysl.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback