[C#/Windows Form] Updaten van Textbox e.d.

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
Ik heb een probleem in C#, waar ik niet uitkom. Ik weet dat het iets fundamenteels is, maar ik begrijp het niet helemaal.

Ik heb 2 classes. In class 1, staat de button1_Click functie. Deze start de 2e Test-class. Hierin wil ik graag een textbox op het formulier vullen met text.

Ik heb de volgende code, maar deze werkt niet. Wat doe ik fout ?

C#:
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
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test test = new Test();
            test.changeText("Button Pressed");
        }
    }

    public class Test
    {
        
        public Test()
        {
            //constructor
        }

        public void changeText(string newText)
        {
            textBox1.Text = newText;
        }


Ik ben een beginner als het gaat om programmeren in C#. Heb al diverse bronnen gezocht, zoals Tweakers, MSDN, Google en heb hier zelfs een aantal Microsoft boeken liggen. Voor wat ik begrepen heb, krijg ik dit werkend d.m.v. invoke() en delegates, maar ik snap het niet.

Iemand die mij wat meer duidelijkheid kan geven in deze ?

edit: Ik gebruik overigens Visual Studio .NET 2005

Verwijderd

Standaard zijn controls op een form private, dus kan alleen het form zelf erbij. Wil je er van buitenaf ook bij kunnen, dan moet je 'm public maken (kun je in de properties van dat control kiezen).

Overigens past Test in jouw geval wel textBox1.Text aan, maar dan van z'n eigen form. Het is nl. een afgeleide van Form1, die maak je netjes aan, maar je toont 'm nooit.

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
Verwijderd schreef op zondag 27 augustus 2006 @ 14:02:
Standaard zijn controls op een form private, dus kan alleen het form zelf erbij. Wil je er van buitenaf ook bij kunnen, dan moet je 'm public maken (kun je in de properties van dat control kiezen).

Overigens past Test in jouw geval wel textBox1.Text aan, maar dan van z'n eigen form. Het is nl. een afgeleide van Form1, die maak je netjes aan, maar je toont 'm nooit.
Ik heb op het standaard form de textbox al public gemaakt. Maar zelfs dan, kan ik hem niet aanspreken :S Daarom dacht ik, dat ik moest overerven.

Form1 is overigens het form waar de button en textbox opstaat hoor :)

Hoe spreek ik hem dan alsnog aan ?

[ Voor 5% gewijzigd door Massiefje op 27-08-2006 14:14 ]


Verwijderd

Je hebt denk ik een klein beetje niet door hoe inheritance werkt.
Jouw Test class is in principe een copie van je Form1 class, met een ChangeText toevoeging. Die laat je textBox1 wijzigen, maar dat is dan de textBox1 van die copie, en niet van de instance van je Form1 class.
Je kunt dit oplossen door ChangeText te vertellen welke TextBox 'ie moet wijzigen door die als parameter door te geven, maar ik vraag me af waarom je daar een class voor nodig zou hebben die afgeleid is van je Form1...

Ik zou zeggen, duik 's in die Microsoft boeken. ;)

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 04-12-2025
Misschien kun je super.text.Text of parent.text.Text aanroepen?

[ Voor 47% gewijzigd door Slagroom op 27-08-2006 14:19 ]


  • zeroxcool
  • Registratie: Januari 2001
  • Laatst online: 14-02 11:55
Massiefje schreef op zondag 27 augustus 2006 @ 14:05:
Form1 is overigens het form waar de button en textbox opstaat hoor :)

Hoe spreek ik hem dan alsnog aan ?
Dan doe je als je het mij vraagt al helemaaaaal moeilijk:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "Button Pressed";
               
        }
    }

zeroxcool.net - curity.eu


Verwijderd

Slagroom schreef op zondag 27 augustus 2006 @ 14:19:
Misschien kun je super.text.Text of parent.text.Text aanroepen?
super is volgens mij de java equivalent van base in c#? Dan gaat dat ook niet werken.
parent zou kunnen, maar dan moet je in de constructor van Test wel vertellen wie z'n parent is.

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
Kleine aanpassing in mijn code gemaakt. Test is nu geen inherited class van Form1 meer.

Form1 is overigens het standaard Windows Form wat aangemaakt wordt bij het beginnen met een Windows Applicatie.

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Het is niet mogelijk op de manier zoals jij het probeert, aangezien itt java, innerclasses volgens mij in c# meer weg hebben van static innerclasses van java; anders gezegd, een nested class in c# brengt geen implicaties met zich mee zoals dat wel het geval is bij java. Zonder static modifier voor de nested class zou in java de implicatie voor die innerclass zijn dat een outerclass instantie eerst vereist is alvorens de innerclass geinstantieerd kan worden binnen die outer class. Dat alles verandert wanneer je de innerclass klassengebonden maakt aan z'n outerclass; je kan dus de innerclass instantieren zonder de outerclass daarvoor te instantieren.
Als ik kijk naar je manier van denken adhv je code ben je wel op de goede weg richting MVC; je bent er van bewust dat je afhandeling van events over wil laten aan andere componenten en in zulke gevallen komt de controller dus om de hoek kijken. Ik kan je aanraden om als beginner niet C# + winforms via visual studio.net te leren, omdat deze de event wireup automagisch voor je doet. Visual studio zou je dan opzich wel kunnen gebruiken maar dan wel zonder de designer.
Wanneer je het dus met de hand doet leer je ook hoe je zelf je eventhandlers moet schrijven, wat nu door visual studio designer gelinked is aan code in je view. Opzich niet zo'n probleem mee, maar je m'n punt is eerder dat je moet weten wat je doet voordat je met zulke designers werkt die het leven makkelijker maken... indien je wederom weet wat je doet.
[edit]
Een workaround tov van hoe je het nu zou hebben is eventueel een referentie mee te sturen van de outer naar de innerclass.

[ Voor 4% gewijzigd door prototype op 27-08-2006 18:25 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 20:35
Op welke manier zou de Test class moeten weten wat textBox1 is ?

Eigenlijk zou je er moeten voor zorgen dat je Test class een referentie heeft naar hetgeen er moet ge-updated worden.
Bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test
{
    private TextBox aTextBox;

    public Test( TextBox textBoxToUpdate )
    {
       aTextBox = textBoxToUpdate;
    }

    public void ChangeText( string msg )
    {
        aTextBox.Text = msg;
    }
}

En dan gebruik je die zo:
code:
1
2
3
4
5
public void Button1_Click( object sender, EventArgs e )
{
   Text t = new Test(textBox1);
   t.ChangeText ("bliep");
}

https://fgheysels.github.io/


  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
prototype schreef op zondag 27 augustus 2006 @ 18:12:
Het is niet mogelijk op de manier zoals jij het probeert, aangezien itt java, innerclasses volgens mij in c# meer weg hebben van static innerclasses van java; anders gezegd, een nested class in c# brengt geen implicaties met zich mee zoals dat wel het geval is bij java. Zonder static modifier voor de nested class zou in java de implicatie voor die innerclass zijn dat een outerclass instantie eerst vereist is alvorens de innerclass geinstantieerd kan worden binnen die outer class. Dat alles verandert wanneer je de innerclass klassengebonden maakt aan z'n outerclass; je kan dus de innerclass instantieren zonder de outerclass daarvoor te instantieren.
Als ik kijk naar je manier van denken adhv je code ben je wel op de goede weg richting MVC; je bent er van bewust dat je afhandeling van events over wil laten aan andere componenten en in zulke gevallen komt de controller dus om de hoek kijken. Ik kan je aanraden om als beginner niet C# + winforms via visual studio.net te leren, omdat deze de event wireup automagisch voor je doet. Visual studio zou je dan opzich wel kunnen gebruiken maar dan wel zonder de designer.
Wanneer je het dus met de hand doet leer je ook hoe je zelf je eventhandlers moet schrijven, wat nu door visual studio designer gelinked is aan code in je view. Opzich niet zo'n probleem mee, maar je m'n punt is eerder dat je moet weten wat je doet voordat je met zulke designers werkt die het leven makkelijker maken... indien je wederom weet wat je doet.
[edit]
Een workaround tov van hoe je het nu zou hebben is eventueel een referentie mee te sturen van de outer naar de innerclass.
Hier ben ik mij van bewust, dat ik beter kan beginnen met standaard code. Alleen ik ben eigenwijs en duik liever in het diepe en los dan problemen op. Daar leer ik meer van (vind ik). Bovendien moet ik altijd een doel hebben om te programmeren. Een doel om een console app te maken heb ik niet echt :)

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
whoami schreef op zondag 27 augustus 2006 @ 18:22:
Op welke manier zou de Test class moeten weten wat textBox1 is ?

Eigenlijk zou je er moeten voor zorgen dat je Test class een referentie heeft naar hetgeen er moet ge-updated worden.
Bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test
{
    private TextBox aTextBox;

    public Test( TextBox textBoxToUpdate )
    {
       aTextBox = textBoxToUpdate;
    }

    public void ChangeText( string msg )
    {
        aTextBox.Text = msg;
    }
}

En dan gebruik je die zo:
code:
1
2
3
4
5
public void Button1_Click( object sender, EventArgs e )
{
   Text t = new Test(textBox1);
   t.ChangeText ("bliep");
}
Dit werkt ! Is dit echter de normale manier van werken? Of is dit een workaround ?

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:35
Nouja, is dit de manier van werken ? Tja... het is een oplossing, maar of het een goede oplossing is voor hetgeen jij wilt, dat weet ik niet, aangezien ik niet weet wat je nu eigenlijk wilt doen / bereiken.

Daarnaast denk ik, dat het toch beter is om te beginnen bij het begin. Je hebt toch ook eerst leren gaan, voor je hebt leren lopen ?

https://fgheysels.github.io/


  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
whoami schreef op zondag 27 augustus 2006 @ 21:02:
Nouja, is dit de manier van werken ? Tja... het is een oplossing, maar of het een goede oplossing is voor hetgeen jij wilt, dat weet ik niet, aangezien ik niet weet wat je nu eigenlijk wilt doen / bereiken.

Daarnaast denk ik, dat het toch beter is om te beginnen bij het begin. Je hebt toch ook eerst leren gaan, voor je hebt leren lopen ?
Ik weet dat je gelijk hebt, hoor. Dat zal ik niet ontkennen. Maar ik ken mezelf. Ik stort mezelf in het diepe en ik leer meer. Trust me.

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:35
Nouja, elk zijn goesting, maar hoe kan je méér leren als je bepaalde basis-dingen mist ?
Een huis dat op slechte fundamenten gebouwd is, deugt ook niet.

https://fgheysels.github.io/


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

nog een kleine tip: Implementeer een functie als ChangeText in je Form1 class, immers je bewerkt er het form mee:
C#:
1
2
3
4
5
6
7
8
9
public partial class Form1 : Form
{
    public void ChangeText(String NieuweText)
    {
        this.TextBox1.Text = NieuweText;
    }

    /* andere functies */
}


je kan dan een aanroep als
C#:
1
2
Form1 UserInterface;
UserInterface.ChangeText("jeuj");

wat logischer "klinkt".

Tevens heeft dit als voordeel dat als je ooit je Form1 verandert (bijvoorbeeld: je wilt ipv TextBox1 een ComboBox12 gebruiken, je alleen de functie in de Form1 class hoeft te veranderen, en niet in alle aanroepende classes)

Ander voorbeeld, als je ooit jouw Form1 in een multithreaded omgeving wilt gebruiken, hoef je alleen Invoke()'s in Form1 te zetten ;)

(maar goed, wellicht dat jij iets anders wilt bereiken dan ik denk dat je wilt bereiken)

-niks-


  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
MLM schreef op zondag 27 augustus 2006 @ 22:25:
nog een kleine tip: Implementeer een functie als ChangeText in je Form1 class, immers je bewerkt er het form mee:
C#:
1
2
3
4
5
6
7
8
9
public partial class Form1 : Form
{
    public void ChangeText(String NieuweText)
    {
        this.TextBox1.Text = NieuweText;
    }

    /* andere functies */
}


je kan dan een aanroep als
C#:
1
2
Form1 UserInterface;
UserInterface.ChangeText("jeuj");

wat logischer "klinkt".

Tevens heeft dit als voordeel dat als je ooit je Form1 verandert (bijvoorbeeld: je wilt ipv TextBox1 een ComboBox12 gebruiken, je alleen de functie in de Form1 class hoeft te veranderen, en niet in alle aanroepende classes)

Ander voorbeeld, als je ooit jouw Form1 in een multithreaded omgeving wilt gebruiken, hoef je alleen Invoke()'s in Form1 te zetten ;)

(maar goed, wellicht dat jij iets anders wilt bereiken dan ik denk dat je wilt bereiken)
Misschien handig dat ik even uitleg wat ik wil gaan doen (en ook al heb, maar dan zonder bovenstaande uitleg).

Ik heb een Canon EOS 350D. Deze zet de foto's allemaal in DCIM mapjes. Ik fotografeer vaak RAW en JPEG door elkaar (of gecombineerd) en deze staan hier dus ook door elkaar in de map DCIM.

Nu heb ik een klein progje gemaakt. Je selecteert bron map, je selecteert doelmap en en vervolgens druk je op de knop "SORT". Dan loopt hij alle bestanden en (sub)folders uit de bronmap langs en zal in de doelmap een map JPG een map CR2 en een map OTHER aanmaken.

Zo kan ik dus makkelijk mijn foto's sorteren.

Doel van topic: Ik wil graag in mijn sorteerfunctie het resultaat laten wegschrijven in een RichTextBox. En dat lukte me dus niet ;)

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:35
Wat je kan doen, is een class maken die deze Sort functionaliteit implementeert.
Deze class geef je dan een event 'Report' bijvoorbeeld, en op de gepaste momenten raise je die event.

Bv:
code:
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
public delegate void ReportHandler( string msg );

public class PictureSorter
{

   public event ReportHandler Report;

   public void Sort()
   {
       while( ... )
       {
            ...
            OnReport(picture " + pict.Name + " moved to .. .");
            ...
       }
   }

   protected void OnReport( string msg )
   {
      if( Report != null )
      {
          Report(msg);
      }
   }

}


Dan gebruik je dit als volgt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Windows form
private void Button1_Click(object sender, EventArgs e )
{
     PictureSorter s = new PictureSorter();
    
     s.Report += new ReportHandler(ReportIt);

     s.Sort();
}

private void ReportIt( string message )
{
   textBox1.Text = message;
}


Om het geheel responsief te houden, kan je die Sort natuurlijk op een andere thread uitvoeren. Dit kan je doen door bv gebruik te maken van het 'Task' pattern.
Dan moet je er wel ook nog op letten dat je je event-handler op de goede thread (de UI thread in dit geval) uitvoert. Dit doe je dmv Invoke te gebruiken.
Voor meer info, zie klik en hier

https://fgheysels.github.io/


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Massiefje schreef op zondag 27 augustus 2006 @ 20:42:
[...]


Hier ben ik mij van bewust, dat ik beter kan beginnen met standaard code. Alleen ik ben eigenwijs en duik liever in het diepe en los dan problemen op. Daar leer ik meer van (vind ik). Bovendien moet ik altijd een doel hebben om te programmeren. Een doel om een console app te maken heb ik niet echt :)
Mjah, just my 2 cents, vooral omdat ik denk dat elke ontwikkelaar wel ergens zo is begonnen, maar later ook inziet dat via trial-en-error niet de meest efficiente danwel effectieve methode is om te leren...denk aan verkeerde code samples dat propageert tot slechte practices overnemen(die je welliswaar later kan verbeteren, maar waarom later als het ook meteen kan denkt de pragmatische ik).
Verder leer je nu ook vooral omdat mensen bereid zijn je te helpen met zulke basic vragen, maar dat is afaik niet echt de bedoeling hier op GoT...

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 21:42
prototype schreef op maandag 28 augustus 2006 @ 00:01:
[...]

Mjah, just my 2 cents, vooral omdat ik denk dat elke ontwikkelaar wel ergens zo is begonnen, maar later ook inziet dat via trial-en-error niet de meest efficiente danwel effectieve methode is om te leren...denk aan verkeerde code samples dat propageert tot slechte practices overnemen(die je welliswaar later kan verbeteren, maar waarom later als het ook meteen kan denkt de pragmatische ik).
Verder leer je nu ook vooral omdat mensen bereid zijn je te helpen met zulke basic vragen, maar dat is afaik niet echt de bedoeling hier op GoT...
Ik ben ondertussen ook wel bezig om van begin tot het eind de boeken te lezen hoor. Alleen ondertussen wil ik niet blijven hangen bij:
C#:
1
2
3
4
public static void Main(string[] args)
{
  Console.WriteLine("Hello, World!");
}

met een uitbreiding van:
C#:
1
2
3
4
public static void Main(string[] args)
{
  Console.WriteLine(args[0]);
}

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Massiefje schreef op donderdag 07 september 2006 @ 15:48:
[...]


Ik ben ondertussen ook wel bezig om van begin tot het eind de boeken te lezen hoor. Alleen ondertussen wil ik niet blijven hangen bij:
C#:
1
2
3
4
public static void Main(string[] args)
{
  Console.WriteLine("Hello, World!");
}

met een uitbreiding van:
C#:
1
2
3
4
public static void Main(string[] args)
{
  Console.WriteLine(args[0]);
}
Geduld is een schone zaak, er is een reden waarom dit zo incrementeel verloopt via boeken. Het heet niets voor niets 'fundamentals'. Maar goed, succes.

  • D4Skunk
  • Registratie: Juni 2003
  • Laatst online: 20-10-2025

D4Skunk

Kind of Blue

C#:
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
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ////////////////////////////////////////
            // Zit dit er in : ??? /////
            ////////////////////////////////////////
            button1.Click +=new EventHandler(button1_Click);
            ////////////////////////////////////////
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test test = new Test();
            test.changeText("Button Pressed");
        }
    }

    public class Test
    {
        
        public Test()
        {
            //constructor
        }

        public void changeText(string newText)
        {
            textBox1.Text = newText;
        }
Pagina: 1