Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
In jouw geval kan je dus een event OnStatusChanged oid gaan maken in je class:
1
2
3
4
| class XmlClass
{
public event EventHandler StatusChanged;
} |
(Nu maak je een event van het type EventHandler, waarmee je misschien wel wat beperkt bent. Misschien is het dus beter om je eigen delegate te gaan maken:
1
| public delegate void MyOwnEventHandler(object sender, string message); |
Je kan dan dus dit type gaan gebruiken voor jouw event.
In je XmlClass maak je dan ook een method waarmee je die event kunt gaan triggern:
1
2
3
4
5
6
7
8
9
10
11
12
13
| class XmlClass
{
public event MyOwnEventHandler StatusChanged;
protected void InvokeStatusChanged(string statusText)
{
if( this.StatusChanged != null )
{
this.StatusChanged(this, statusText);
}
}
} |
Zo, nu is je XmlClass klaar. Het enige wat je nu nog moet doen, is in de form waarin je die class gebruikt, een method te gaan koppelen aan je eigen event (StatusChanged).
Die method moet voldoen aan de 'signature' die je gespecifeerd hebt in je delegate definitie:
1
2
| XmlClass myXmlObj = new XmlClass(); myXmlObj.StatusChanged += new MyOwnEventHandler(this.UpdateStatusBar); |
De UpdateStatusBar method in je form ziet er dan dus bv zo uit:
1
2
3
4
| public void UpdateStatusBar(object sender, string displayMessage)
{
this.myStatusBar.Text = displayMessage;
} |
https://fgheysels.github.io/
ik ga het meteen ff proberen!
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
in je XmlClass moet je natuurlijk ook nog je event gaan triggeren om je statusbar te gaan updaten:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| public class XmlClass
{
...
public void DoWork()
{
...
// Open Xml File
InvokeOnStatusChanged("Opening xml file...");
..
// Processing
InvokeOnStatusChanged("Processing file...");
...
}
} |
Code is uit de losse hand getyped, dus er zullen wel wat foutjes enzo inzitten, maar je zou het idee wel moeten snappen...
https://fgheysels.github.io/
moet ik nu zowel
1
| public event MyOwnEventHandler StatusChanged; |
als
1
| public delegate void MyOwnEventHandler(object sender, string message); |
zetten?
de compiler kan namelijk MyOwnEventHandler niet vinden in de form.
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Dit kan je doen door te checken wat het 'target' van de delegate is, en als het 'target' een Windows Control is, dan zal je er moeten voor zorgen dat die method aangeroepen wordt in de context van de thread die die control gecreeërd heeft (meestal de main thread).
Concreet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| protected void InvokeOnStatusChanged ( string messageText )
{
if( StatusChanged != null )
{
System.Windows.Control c = StatusChanged.Target as System.Windows.Control;
if( c == null )
{
StatusChanged(this, messageText);
}
else
{
c.Invoke(StatusChanged, new object[] {messageText});
}
}
} |
https://fgheysels.github.io/
Hoe bedoel je ?4of9 schreef op dinsdag 07 december 2004 @ 11:03:
oke ik ben al een eind op weg.
moet ik nu zowel
code:
1 public event MyOwnEventHandler StatusChanged;
als
code:
1 public delegate void MyOwnEventHandler(object sender, string message);
zetten?
de compiler kan namelijk MyOwnEventHandler niet vinden in de form.
Die beide lijnen code moet je er idd zetten, echter die delegate is een type, dus dat moet je buiten je XmlClass zetten.
https://fgheysels.github.io/
nu moet ik alleen tijdens het writen van de xmlfile zelf op ieder punt dat ik een status wil weergeven een InvokeStatusChanged doen.
Is er ook een manier om bijvoorbeeld automatisch de status weer te geven als ik de methode aanroep waarvan ik de status messages wil laten zien?
(een link of tutorial is ook oke hoor
ik ben helaas nog niet op het niveau om multithreading te gaan gebruiken, dus is dat checken echt nodig? en zo ja waarom? thx again!
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Hoe bedoel je ?4of9 schreef op dinsdag 07 december 2004 @ 11:16:
Is er ook een manier om bijvoorbeeld automatisch de status weer te geven als ik de methode aanroep waarvan ik de status messages wil laten zien?
https://fgheysels.github.io/
iedere keer als ik nu in mijn writeXML method een statusupdate wil laten zien, moet ik die invokeStatusChange aanroepen.
Ik zoek een manier om tijdens het uitvoeren van het programma, automatisch status messages laten zien (in de volgorder van doorlopen van het programma) als dat mogelijk is.
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
InvokeEventName vind ik niet zo netjes, op MSDN vertellen ze je OnEventName te gebruiken.
Alleen jouw XMLClass kan toch weten wanneer er een status change is? Laat ik het anders stellen, waar zou een andere class de informatie over de status van jouw XMLClass kunnen opvragen?4of9 schreef op dinsdag 07 december 2004 @ 11:23:
in de xmlTextWriter class zit een property "writestate"
iedere keer als ik nu in mijn writeXML method een statusupdate wil laten zien, moet ik die invokeStatusChange aanroepen.
Ik zoek een manier om tijdens het uitvoeren van het programma, automatisch status messages laten zien (in de volgorder van doorlopen van het programma) als dat mogelijk is.
IMHO moet een processing class altijd degene zijn die dmv events de aanroeper laat weten hoe het ervoor staat.
Ja zo wil ik het ook, alleen lijkt het me niet "netjes" om iedere keer handmatig te bepalen wanneer dat er een statuschange plaatsvind.bigbeng schreef op dinsdag 07 december 2004 @ 11:33:
[...]
Alleen jouw XMLClass kan toch weten wanneer er een status change is? Laat ik het anders stellen, waar zou een andere class de informatie over de status van jouw XMLClass kunnen opvragen?
IMHO moet een processing class altijd degene zijn die dmv events de aanroeper laat weten hoe het ervoor staat.
In het geval van de writestate van de xmlwriter class vind bij iedere stap een writestate verandering plaats.
Mijn vraag is nu, als ik de writeXML method toevoeg, hoe zorg ik er dan voor dat er zoiets als dit uitgevoerd word (als dat al kan)
pseudo code
1
2
3
4
5
6
7
8
9
| public void writeXML()
{
...
//open xmlfile en schrijf weg
//laat tijdens uitvoeren de status zien
if(xmlwriter.WriteState= veranderd)
OnStatusChange(xmlwriter.WriteState.ToString());
} |
zoiets dus.
zoals ik al zei, OO is voor mij redelijk nieuw dus vandaar mijn stortvloed aan vragen, ondanks dat ik met een boek op mijn schoot zit
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Alleen jouw class kan dat weten.4of9 schreef op dinsdag 07 december 2004 @ 11:40:
[...]
Ja zo wil ik het ook, alleen lijkt het me niet "netjes" om iedere keer handmatig te bepalen wanneer dat er een statuschange plaatsvind.
Moest die XmlWriter nu een event hebben dat getriggered wordt als de WriteState veranderd, dan zou je daar wat mee kunnen aanvangen.In het geval van de writestate van de xmlwriter class vind bij iedere stap een writestate verandering plaats.
[quote]
Mijn vraag is nu, als ik de writeXML method toevoeg, hoe zorg ik er dan voor dat er zoiets als dit uitgevoerd word (als dat al kan)
Aangezien die XmlTextWriter dus geen event heeft dat je kan gebruiken, AFAIK niet.
https://fgheysels.github.io/
ik ben al weer een stuk wijzer
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
In mijn form class maak ik een instantie aan van de DataBaseClass.
Nu werkt dat prima, ik maak deze aan samen met de Class members.
Maar wat is nu de goede plek om deze DataBaseClass aan te maken.
Mijn gedachte was namlijk in de constructor van de form class, alleen begint de compiler dan te roepen dat de instantie van de DataBaseClass nog niet bestaat.
ik gebruik deze namelijk in een method.
In de constructor worden ook eventhandlers toegevoegd die naar de DataBaseClass verwijzen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| namespace iets
{
Class FormClass
{
public FormClass()
{
// Hier?
// DatBaseClass DB = new DataBaseClass();
DB.StatusChanged += new getDataEventHandler(this.UpdateStatusBar);
}
private void fillDataSet(string sp)
{
hours = DB.getData(sp);
}
private void Button1_Click()
{
fillDataSet(sp);
//doe wat met dataset enzo
}
// waarom hier en niet in de constructor?
DatBaseClass DB = new DataBaseClass();
}
} |
ondanks dat het werkt snap ik niet helemaal waarom het niet in de constructor kan?
Bedankt weer!
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
1
2
3
4
5
6
7
8
9
10
| class MyForm
{
private DataBaseClass DB;
public MyForm()
{
// Constructor
DB = new DataBaseClass();
}
} |
https://fgheysels.github.io/
Waarom moet dat in de contructor op die manier?
en wat is de meest nette manier om het te doen?
in de constructor of gewoon zoals ik het nu doe?
thx! ik leer vandaag een hoop meer dan uit zo'n boek lezen/overtikken....
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Als je een variable op form - niveau declareert, bestaat die waarde voor je hele form.
Declareer je een variable binnen een functie/method, dan bestaat die variable enkel binnen die method. (Een constructor is ook een method).
Aangezien je die DataBase class waarschijnlijk zo een beetje overal in je form nodig zult hebben, zal je hem dus op 'Form niveau' moeten declareren.
Je moet 'm dan natuurlijk ook nog initializeren, en dat kan je dan doen in je constructor, of direct bij de declaratie.
https://fgheysels.github.io/
Ik dacht dat de constructor een speciale method was waar niet hetzelfde opging als voor andere methods, vandaar deze verwarring!
Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...
Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack
Ik zou m'n gegevens ophalen dmv een 'data access component', en die component die gegevens laten returnen. In je GUI kan je dan die component aanspreken, de gegevens verkrijgen en je ListView gaan inlezen.riezebosch schreef op dinsdag 07 december 2004 @ 16:55:
Nu wil ik graag m'n logica beetje van m'n gui scheiden. Is het dan verstandig het openen en opslaan van bestanden een laag dieper te brengen? En moet ik dan ook op dezelfde manier de listview met gegevens vullen zoals hierboven aangegeven?
Je mag het inlezen van de listview zeker niet over laten aan een component die 'dieper' zit, aangezien die componenten eigenlijk niets mogen afweten van de GUI, anders kan je die componenten nooit makkelijk gaan 'hergebruiken' in een andere GUI.
zo dus:
1
2
3
4
5
6
7
8
9
10
11
12
| private ButtonLoad_Click( object sender, EventArgs e )
{
// dit is dus een method in je windows applicatie.
// Roep je 'data access component aan', en verkrijg de gegevens.
myCustomerCollection = customerDataAccessComponent.GetCustomers();
// Laad de ListView in met gegevens die in de myCustomerCollection zitten.
this.LoadCustomerListView (myCustomerCollection);
} |
Wat het openen en sluiten en writen naar bestanden betreft: die kan je best in een andere component gaan plaatsen, mits je aan die component doorgeeft waar hij de bestanden moet plaatsen of kan vinden.
Zorg er ook voor dat die component steeds de bestanden sluit als ie ze niet meer nodig heeft (try/finally clause).
[ Voor 14% gewijzigd door whoami op 07-12-2004 17:00 ]
https://fgheysels.github.io/
Ik heb dit:
1
2
3
4
5
6
7
8
9
10
11
12
13
| public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.ListBox listBox1; private System.Windows.Forms.Button button1; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; private Class1 bla; public delegate void MyOwnEventHandler(object sender, string msg); <snip> } |
1
2
3
4
5
| private void button1_Click(object sender, System.EventArgs e) { bla = new Class1(); bla.StatusChanged += new MyOwnEventHandler(); } |
in class.cs heb ik het volgende:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| using System; using System.Threading ; namespace WindowsApplication3 { /// <summary> /// Summary description for Class1. /// </summary> public class Class1 { int i; public event MyOwnEventHandler StatusChanged; protected void InvokeOnStatusUpdated(string msg) { if (this.StatusChanged != null) { System.Windows .Control c = StatusChanged.Target as System.Windows.Control; if (c==null) { StatusChanged (this, msg); } else { c.Invoke(StatusChanged, new object []{msg}); } } } public Class1() { Thread bla = new Thread(new ThreadStart(blaat)); } public void blaat() { i++; InvokeOnStatusChanged("Bla"); } } } |
als ik compileer krijg ik de volgende foutmelding:
Class1.cs(12): The type or namespace name 'MyOwnEventHandler' could not be found (are you missing a using directive or an assembly reference?)
Maar ik kom er dus niet uit! Ik heb al gegoogled, maar ik kom er echt niet uit:(
PS. Ik gebruik visual studio 2003 (geen 2005 dus, als dat al verschil uitmaakt)
Ik heb zoiets een tijdje geleden ook al gevraagd, maar was er door tijdgebrek niet meer aan toegekomen. Die threads nog wel doorgenomen, maar ik kom er echt niet uit
Memories of yesterday, will grow, but never die
ben er eindelijk achter! Ben nu echt blij dat ik het eindelijk een keer doorheb!
Alleen nog een vraagje:
Is de code die hier dus was gegeven, de juiste manier om objecten op het form te veranderen//te updaten? Of is er ook nog een nettere manier hiervoor?
Memories of yesterday, will grow, but never die