Přístup do FORM z funkce   zodpovězená otázka

VB.NET, Komponenty, WinForms

Dobrý den,mám vytvořený FORM1 jako třídu, a potřebuji na tento formulář zobrazovat graficky provozní stavy. Pokud se nacházím ve FORM1, není problém. Vzhledem k přehlednosti v programu při následných úpravách by však bylo vhodnější, kdyby bylo možné do formuláře přistupovat z funkce nebo procedury.

Ve FORM1 nakreslím čáru například takto e.Graphics.DrawLine(Barva, X1, Y1, X2, Y2). Jakým způsobem je možné volat FORM1 s podobnými parametry, aby se vykreslila v tomto formuláři stejná linka? Nebo je nějaký vhodnější způsob?

Děkuji za pomoc a radu.

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

Dejme tomu, že hlavní okno aplikace bude Form0. Form1 bude okno, do kterého se bude kreslit. Form0 vytvoří instanci Form1 a napojí svojí Private metodu na událost Paint od Form1. Tato Private metoda bude zajišťovat samotné vykreslování, které proběhne vždy když to bude potřeba (při žádosti Form1 na překreslení). Kreslit budete pomocí objektu Graphics který dostanete jako jeden z parametrů události Paint.

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

No, to, na co se kreslí, je e.Graphics. Můžete tedy zavolat jakoukoliv metodu, která bude kdekoliv (třeba v nějakém formuláři, nebo i třídě či modulu) a jako parametr jí předat to e.Graphics. Pak na něj vykreslíte, co chcete, a objeví se to na tom formuláři, jehož objekt Graphics jste předal.

'můžete si do projektu přidat modul, v okně Solution Explorer 
'klikněte pravým tlačítkem a přidejte tam novou položku Module
Module Module1

    Public Sub VykresliCaru(g As Graphics)
        'nyní nemáme e.Graphics, ale g, kreslíme do g
        'samozřejmě si můžete přidat i další parametry
        g.DrawLine(Color.Black, 0, 0, 100, 100)
    End Sub 

End Module

A ve formuláři pak zavoláte tohle:

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs)
    VykresliCaru(e.Graphics)  'předáme e.Graphics jako parametr g
End Sub

Výhodou je, že tuto funkci v modulu můžete volat z různých formulářů, takže můžete díky tomu vykreslovat kam chcete (na formulář Form1, nebo třeba i na tiskárnu).

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

Můžeme taky pro jistotu přenášet jen referenci:

    Public Sub VykresliCaru(ByRef g As Graphics)
        'nyní nemáme e.Graphics, ale g, kreslíme do g
        'samozřejmě si můžete přidat i další parametry
        g.DrawLine(Color.Black, 0, 0, 100, 100)
    End Sub 

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

Ona se ta reference přenese i v případě ByValu pokud se jedná o referenční typ... Klíčové slovo ByRef slouží k tomu, aby bylo možné změnit hodnotu proměnné označené právě tímto klíčovým slovem. Takže pozor na to.

Dim obj As New Object

Sub DoSomething(ByVal x As Object)
  x = Nothing
End Sub

Sub DoSomethingElse(ByRef x As Object)
  x = Nothing
End Sub

Sub Main()
  'obj zůstane beze změny
  DoSomething(obj)
  'obj bude nastaveno na Nothing a to je význam ByRef
  DoSomethingElse(obj)
End Sub

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

Já vím.... akorát jsem myslel, že by to bylo jistější, když už se to přenáší

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

Jak "jistější"? Jistější by to právě vůbec nebylo, protože metoda by potom měla možnost změnit předávanou hodnotu a mohla by jí taky klidně nastavit na Nothing což by mohlo zbořit zbytek aplikace. Obecně bych doporučoval ByRef vůbec nepoužívat, jediné kde sem tohle viděl a k něčemu to bylo jsou metody TryParse.

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

To je zbytečné, Graphics je objekt. ByRef by v tomto případě mělo smysl pouze pokud byste chtěl v metodě, která tuhle zavolala, změnit to, co je uloženo v e.Graphics, což by asi stejně nešlo, protože je to readonly property.

V drtivé většině případů stačí ByVal, ať už pro objekty, nebo pro jednoduché datové typy. Rozmyslet je to potřeba u větších struktur, aby se při volání funkce nekopírovalo zbytečně moc paměti, anebo pokud chcete vracet jednou funkcí víc hodnot, případně nastavovat proměnné. Ale v 99% případů vyhovuje ByVal.

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

Díky za radu, funguje to, pouze v g.DrawLine jsem musel změnit barvu na pero (z Color.black na Pens.Black).

Ještě jednou díky.

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