Vyvolání události s dopadem v jiné třídě – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Vyvolání události s dopadem v jiné třídě – .NET – Fórum – Programujte.comVyvolání události s dopadem v jiné třídě – .NET – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
nirman0
Duch
26. 11. 2012   #1
-
0
-

Zdravíčko, mám zákys. Snažím se napsat TCP komunikátor klient-server-klient. V úplném začátku (jeden thread jeden stream a prevod z konzolovky do Formu) jsem narazil na problém nastávající:

V klientské aplikaci mám:
Třídu Form, tam zkrátka je jakýsi richTextBox_myMessage kam klient píše, button kterým to klient odpálí na server a richTextBox_conversation, kde se vytváří log z komunikace (příchozí a odchozí dokupy).

Dál třídu Client, v té hned ze začátku písknu na server, ten vytvoří NetworkStream. Pak je tam metoda Sent(string message), kterou zavolá button a do parametru jí šlehne richTextBox_myMessage.Text. No a blížíme s k problému... ten jest v metodě Listen().
Metoda Listen() je po vytvoření streamu volána samostatným threadem. Její úkol je prostý - v nekonečném cyklu poslouchá stream a v případě, že přijde zpráva od serveru, tak ji vezme a dekóduje. Výsledkem je string.

Můj problém je v tom, že nejsem schopný zařídit, aby se tato nečekaná událost (zpráva, která přijde ze serveru) projevila ve Formu (uložila do richTextBox_conversation). Ze třídy Client si nemůžu dovolit udělat něco jako Form.richTextBox_conversation.Text += string a cyklicky ve Form kontrolovat, jestli něco nepřišlo je stupidní. Při pokusu o vytvoření delegáta jsem zamrzl na tom bodě, že nevím, jak event projevit v jiné třídě, než kde je delegát deklarován. Takže se ptám na možná (i alternativní) řešení, pravděpodobně jak mám udělat event, který "protáhnu" skrze dvě třídy nespojené dědičností.

Nahlásit jako SPAM
IP: 78.102.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 11. 2012   #2
-
0
-

#1 nirman
Můžeš si přece do nějaké "globální" třídy do static proměnné uložit odkaz na ten form a přes ten pak přistupovat k jeho prvkům, akorát budeš muset před tím nastavit CheckForIllegalCrossThreadCalls na false abys mohl k UI přistupovat napříč thready.

A nebo pokud je to v C++ tam pomocí SendMessage posklat WM_SETTEXT na handle toto richeditu.

Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 213.220.211.–
nirman0
Duch
26. 11. 2012   #3
-
0
-

Jde o C#. A k tomu odkazu na form - to nepobiram :D Do objektu ve Form ja nevidim at delam co delam, ale aji jak se snazim, me to prijde jako prasarna to takto resit, proto jsem se uchylil k tem eventum, coz se mi nepodarilo no.

Nahlásit jako SPAM
IP: 78.102.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 11. 2012   #4
-
0
-

#3 nirman
Myslel jsem něco jako si udělat např třídu:

class Globalni
{
  public static FormHlavni form_hlavni = null;
}

a v OnLoad hlavního formu:

Globalni.form_hlavni = this;

a pak to chceš mít přístupné udělat public a přes Globalni.form_hlavni s na to odkazovat, včetně text-boxů apod.

Radek Chalupa
- vývoj software na zakázku
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC)
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 213.220.211.–
ingiraxo+15
Grafoman
26. 11. 2012   #5
-
+1
-
Zajímavé

já ted nevim jestli problém chápu správně... takže ty vlastně chceš... jakmile klient pošle zprávu na server, tak tuto zprávý poslat do formu do boxu?

Pokud jo, tak si vytvoříš normální událost s parametrem string, kde bude zpráva a akorát ji ve formu dáš tělo

tvar události můžeš mít třeba jako 

// udalost na serveru
public event Action<string> ReadMessage;

// dokodovana zprava se posle do udalosti
if (ReadMessage != null)
    ReadMessage(zprava);

// na strane Form jen vytvoris vlastni funkci
private void ReadMessage(string msg) { /* ... */ }

// a v konstruktoru Formu presmerujes udalost
server.ReadMessage += ReadMessage;
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
nirman0
Duch
26. 11. 2012   #6
-
0
-

#5 ingiraxo
Chapes to sice naopak (server odesle zpravu, klient ji prijme a ma ji vypsat do formulare), ale v tomto pripade je to jedno, napsal jsi mi uz z toho jak to vidim to, po cem se pidim. Jadro problemu je asi to, ze neumim poradne zachazet s eventy. Zkusim to, jen nevim, jestli se to bude chovat dynamicky, kdyz to server.ReadMessage += ReadMessage; je v konstruktoru formu a po vytvoreni (dle meho chabeho usudku) uz se to vicekrat nestane. Kdezto zpravy muzou chodit porad. Nic, prubnu a uvidim

Nahlásit jako SPAM
IP: 78.102.98.–
Evzen+2
Návštěvník
27. 11. 2012   #7
-
+1
-
Zajímavé

#6 nirman
ReadMessage bude událost jak napsal Ingiraxo, prostě si jí deklaruješ jako public a zvenčí se na ní budeš registrovat přes toto:

server.ReadMessage += ReadMessage

Kde ReadMessage bude metoda odpovídající předpisu události.

Pak ale ty sám někde v kódu, když ti přijde zpráva, tak budeš vyvolávat událost ReadMessage (ten event). Pokud nikdo nebude registrován, tak se nic neděje, pokud ale zaregistruješ více metod, tak budou všechny notifikovány o čtení zprávy.

Výhoda je v tom, že budeš mít server zapouzdřen, zprávy budeš odesílat třeba pomocí metody SendMessage a pokud nebudeš potřebovat čtení, tak se jednoduše registrovat nemusíš.

Dělal jsem něco obdobného, tak se klidně inspiruj:

http://code.google.com/…rowse/trunk/#…

Evžen

Nahlásit jako SPAM
IP: 193.179.183.–
nirman0
Duch
28. 11. 2012   #8
-
0
-

Tak dobré, prakticky jsem se tu díky vám naučil v praxi použít eventy.. Teď mám problém toho, že když to mám zaobalené do dvou vláken (Thread ve třídě A, hlídající příchozí zprávu chce tuto zprávu odeslat do Form, což je samostatné vlákno). No a vlákna jsem používal dosavadně jinak, jen na rozdělení výpočtů, bez předávání mezi vlákny. Není to už k tomuto tématu, takže děkuji za vyřešení eventu. Teď bojuju s BackgroundWorker, zkrátka kdyby měl někdo chuť mi ještě ukázat jak se s tím robí (nebo lépe než s BW třídou), tak to uvítám, ale tuto diskuzi označuju za vyřešenou. Díky :)

Nahlásit jako SPAM
IP: 78.102.98.–
ingiraxo+15
Grafoman
28. 11. 2012   #9
-
+1
-
Zajímavé

#8 nirman
snad ti to pomůže v boji s BackgroundWorkem

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
nirman0
Duch
28. 11. 2012   #10
-
0
-

Tutorial na youtube by me nenapadlo hledat. Tuz to pujde jak po masle dik :)

Nahlásit jako SPAM
IP: 78.102.98.–
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, 10 hostů

Podobná vlákna

C# vyvolani udalosti — založil cybernick

C# vyvolani události — založil cybernick

Objekt v jine tride — založil gomess

 

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