21. marts 2011 - 09:58Der er
34 kommentarer og 1 løsning
Tråde textbox1
Hej
Jeg kan ikke opdater en textbox i en anden klasse. JEg tror det har noget med at jeg ikke er i samme tråd, men hvordan skal det lige løses. ?? nedenstående kode kan jeg ikke få til at virke
Class Form 1 { private void UpdateText(String logdata)// {
textBox1.Text = logdata; }
}
Class Modem { public delegate void UpdateTextCallback(string text);
TextBox1.Invoke(new UpdateTextCallback(this.UpdateText),new object[]{"Text generated on non-UI thread."}); }
For at kunne opdatere formen fra din Modem klasse, bliver du nød til at oprette en reference til formen i Modem klassen. Dette kan for eksempel være en property som bliver sat fra konstruktøren.
Class Modem { public Form1 OwnerForm{get; private set;}
public Modem(Form1 ownerForm) { this.OwnerForm = ownerForm;
// nu kan du sætte labelen fra Modem klassen, hvis Label1 er sat til at være public. this.OwnerForm.Label1.Text = "test fra modem"; } }
Dette er dog meget dårligt design, da du gør din Modem klasse afhængig af denne form.
Et bedre design vil være at lade Modem klassen være uafhængig. Formen kan da bruge Modem klassen, og opdatere sit brugergrænsesnit alt efter dens state.
Hvis du forklare lidt mere om hvad du prøver at lave, så skal jeg prøve at hjælpe.
Undskyld jeg var lidt langsom om at svare, men jeg havde lidt travlt :)
Her er en god måde at gøre det på.
Her er en Modem klassen: public class Modem { private Timer testTimer;
public Modem() { // Dette er testkode, for at simulere at der kommer nye logbeskeder en gang i sekundet. testTimer = new Timer(1000); testTimer.Elapsed += new ElapsedEventHandler(testTimer_Elapsed); testTimer.Start(); }
private string _logData; public string LogData { get { return _logData; } set { _logData = value; this.OnLogDataChanged(); } }
Det som har med timeren at gøre, er bare testkode for at simulere at der kommer nye logbeskeder en gang i sekundet. Den som sker er, at når LogData propertien bliver ændret, kastet LogDataChanged eventet. Dette event skal du lytte på i formen. Herunder er koden til min form:
public partial class Form1 : Form { public Form1() { InitializeComponent(); }
KAn jeg så bruge this.LogData += string.Format("log entry, tid: {0}\r\n", DateTime.Now.ToString()); som en "funktion" jeg kan indsætte forskellige steder i min kode??
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace Traade { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
Ja, og det gør den også nu. Er det en multiline tekstboks du skriver til? Hvis det er en single line tekstboks, vil du altid kun se den øverste linje. Sådan som den virker nu, lægger den en ny linje til, hver gang du kalder UpdateText.
Hvis du vil have den til at overskrive den gamle tekst, skal du ændre din UpdateText metode, sådan:
Nu har jeg set på din kode. Jeg tror aldrig at UpdateText() metoden bliver kaldt. Du kalder den fra SendSMS metoden, men jeg kan ikke se at du kalder sendSMS() nogen steder fra i din form!
Prøv at sætte et breakpoint inde i UpdateText metoden, for at se om den breaker.
Det du kan se er kun en lille del af den samlede kode, men den kommer igennem SendSMS, for jeg modtager både SMS og jeg får skrevet til min log txt fil.
Blokerer du tråden? Dette kan ske hvis koden suser rundt i en while løkke eller lignende? Et symptom på dette, vil være at formen går i "svarer ikke" mode. Hvis dette sker, vil formen ikke blive opdateret.
Men, jeg skal prøve at se lidt mere på det senere i dag. Lige nu har jeg lidt travlt :)
Ja jeg kunne jo have prøvet at steppe igennem programmet sorry havde jeg ikke lige tænkt på.
Når UpdateText() bliver kaldt, hopper den i methoden, og derefter i LogData(), og OnLogDataChanged(), så køre den if(this.LogDataChanged !=null), og her hopper den over handlingen i if sætningen og køre videre i mit program.
Med mindre du gør noget aktivt for at køre noget kode i en anden tråd, vil det køre i samme tråd som det der kalder koden. Hvis du er i tvivl om du har flere tråde, så har du højest sandsynligt bare en. Med mindre selvfølgelig, at du bruger et eller andet tredjeparts værktøj som opretter nye tråde.
hvis den springer over denne linje: if(this.LogDataChanged !=null), så er det fordi der ikke er tilføjet en event-handler. Det kan kun skyldes 2 ting. Enten har du ikke tilføjet event-handleren, ellers har du oprettet event-handleren på forkert instans af Modem klassen. Event-handlers er aktive, uanset om de bliver kaldt fra andre tråde, så det har ikke noget med det at gøre.
Prøv at brug lidt mere tid til at steppe igennem koden. Kontroller at du tilføjer eventhandleren før du kalder UpdateText, og dobbeltjek at det er rigtig instans du tilføjer eventhandleren på.
Det er denne linje der tilføjer en event-handler. this.modem.LogDataChanged += new EventHandler(modem_LogDataChanged);
Og den tilføjer eventhandleren til this.modem instansen, og ikke andre eventuelt oprettede instanser af klassen.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.