label update in een andere class

Status
Niet open voor verdere reacties.

knarfoe

Gebruiker
Lid geworden
27 apr 2012
Berichten
19
Hallo,

Ik pieker me suf over het volgende.

Ik heb een programmaatje dat een aandelenkoers in de console schrijft.
Dat onderdeel ziet er zo uit:

Code:
class TestPrijsCallBack : PrijsCallback
{
public void OnPrijsupdate(Prijs prijs)
Console.Writeline(price.GetDisplayString());
}

Nu wil ik in de standaard Form1 de label1 updaten met die price.GetDisplayString
Dus bv. form1.label.text = price.GetDisplayString();

maar dat gaat niet zo simpel vanuit een andere class.


wie weet hoe?
gr
frank
 
Laatst bewerkt door een moderator:
Er zij heel wat mogelijk heden om dit voor elkaar te krijgen. Dit is bijvoorbeeld te doen met events. (zoals het form load event, button click event etc)

Code:
public class PriceChanger
{
    public event EventHandler PriceUpdate;

    private double _price;

    public double Price
    {
        get { return _price; }
    }

    public PriceChanger(double initialPrice)
    {
        _price = initialPrice;
    }

    public void IncreasePrice()
    {
        _price += 0.25;
        PriceUpdate(this, EventArgs.Empty);
    }
}

Om dit in een form te gebruiken zou je bijvoorbeeld het volgende kunnen doen.

Zodra je op de knop klikt gebruik je de simpele IncreasePrice() method in de class om de prijs wat hoger te zetten en zodra dit gebeurt wordt het event aangeroepen en zal het label zijn text wijzigen.
Code:
    public partial class Form1 : Form
    {
        private PriceChanger _priceChanger;

        public Form1()
        {
            InitializeComponent();
            _priceChanger = new PriceChanger(1.00);
            _priceChanger.PriceUpdate += new EventHandler(_priceChanger_PriceUpdate);
        }

        void _priceChanger_PriceUpdate(object sender, EventArgs e)
        {
            lblStatus.Text = "The price has been set to " + _priceChanger.Price.ToString("C");
        }

        private void btnIncrease_Click(object sender, EventArgs e)
        {
            _priceChanger.IncreasePrice();
        }
    }

Er zijn nog andere methodes zodat je de price niet uit de class hoeft halen maar uit de meegestuurde event args kunt halen. Maar om mee te beginnen is dit een goede stap.
 
Hoe kan je nu vanuit een andere class _priceChanger.IncreasePrice(); aanroepen?
Ik krijg: The name '_pricechanger' does not exist in the current context
 
Je kunt de price changer in de constructor meegeven, dit kan dus ook bij een form of zo.

Zie voorbeeld:
http://dl.dropbox.com/u/63676419/PriceApplication.zip


f0yu04.jpg


(ook heb je hier meteen een voorbeeld van custom event args, ik heb een PriceEventArgs gemaakt die de huidige prijs mee geeft)
 
ok dit voorbeeld begrijp ik. Die trackingform ziet een event en mag zijn eigen listview updaten.
Maar mijn class TestPrijsCallBack heeft geen form.
Ik wil dat ipv een Console.Writeline dat hij een label update.
Moet ik hiervoor een event gebruiken?
 
Hier zijn wederom veel mogelijk heden. Het hangt wat af van wat je class allemaal doet, en of je hem voor meerdere dingen wilt gebruiken anders dan 1 specifiek label te updaten.

Maak je de class aan in een form waar dat label zit?

Gebruik je de class in een andere class die in verbinding met het form is?
(In zo'n geval wil je zeker geen directe verbinding met het form, dan knoop je alles aan elkaar en moet je alles wijzigen als je iets verandert of een ander form wilt gebruiken etc)

Het is in ieder geval goed dat je niet alles bijeen stopt, zelf heb ik het liefst bijna geen code in het form zelf.

Kun je een voorbeeld geven wat je classes moeten doen (behalve 1 label te updaten)?
 
Laatst bewerkt:
Hi,
Het lukt me niet om uit de aparte classe (class TestPrijsCallBack : PrijsCallback (deze wordt getriggered door een external event))
een label te updaten in form1 in de basis class.
Wat ik nu doe is een globale variabele updaten:

Code:
static class globalvar
    {
        private static string m_GlobalVar = "";
        public static string GlobalVar
        {
            get { return m_GlobalVar; }
            set { m_GlobalVar = value;}
        }
    }

Die kan ik gewoon vanuit Form1 weer uitlezen. eventueel via een aparte Thread die bv. elke 10ms draait.
Maar ik denk dat er toch een makkelijkere manier moet zijn.

Moet ik het met Events kunnen doen?
 
Laatst bewerkt door een moderator:
Nee. Kun je niet gebruik maken van public properties?
Heb het voor de rest niet getest, maar dit moet volgens mij gewoon werken zonder Events.
 
Kun je een voorbeeld uploaden met global, dan zal ik eens kijken. Dan is het ook makkelijker om uit te leggen denk ik. (de voorbeelden hier boven zouden toch al aardig een voorbeeld moeten zijn denk ik)

Je wilt niet dat je callback class dingen op je form moet gaan updaten. Dit zou je dan elke keer moeten wijzigen als je ergens anders ook een label wilt updaten, of een log file wilt maken. Iemand die er iets mee wilt kan gewoon luisteren naar het event and zelf erop reageren wanneer dit gebeurt.

Het idee is dat je de callback class maakt zodat deze niets van de gebruikers van de informatie af hoeft te weten. (anders zou je deze class constant moeten blijven aanpassen).
 
Die globalvar is mooi omdat je hem overal vanaf kunt benaderen. Je hoeft er geen instance van de maken.
Die aparte klasse ziet er nu zo uit:
Code:
class TestPrijsCallback : PrijsCallback
    {
        public delegate void OpeningDoor();
        public event OpeningDoor RaiseDoorOpening;

        public void OnPrijsUpdate(Prijs prijs)
        {
            globalvar.GlobalVar = prijs.GetDisplayString();
            RaiseDoorOpening();
        }
    }


Dus ik plaats eerst de prijs.GetDisplayString in de globalvar en dan raise ik een event.
Die wordt opgepakt in Form1 en schrijft het naar een Label.

Ik vind dit ook wel een mooie oplossing. Databinding.(maar wel een instance maken van Student)
Code:
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 binding
{
    public partial class Form1 : Form
    {
        private Student student = new Student();
        public Form1()
        {
            InitializeComponent();
            textBox1.DataBindings.Add(new Binding("Text", student, "Name"));
        }
        private void button1_Click(object sender, EventArgs e)
        {
            student.Name = DateTime.Now.ToLongTimeString().ToString();
         }

        private void Form1_Load(object sender, EventArgs e)
        {
            student.Name = "Jeff";
        }
    }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace binding
{
     public class Student : INotifyPropertyChanged
    {
        private  string name;
        [System.ComponentModel.Bindable(true)] 
        public  string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged("Name");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }


    }
}
 
Laatst bewerkt door een moderator:
Het principe van het static class doorgeef luik snap ik wel. Maar ik bedoel eigenlijk een voorbeeld waar je je price callback class gebruikt, aanmaakt, events en methods aanroept etc.
Je wilt natuurlijk niet dan alles samenhangt doormiddel van static classes, dan kun je net zo goed je hele price callback static maken :P

En de INotifyPropertyChanged interface is inderdaad een soort gelijk iets.

Het voordeel van de events die je bijvoorbeeld in je pricecallback class zet is bv als je een class / form hebt die alleen maar hoeft te weten (een label te updaten of een mail versturen of wat dan ook) wanneer de prijs omlaag gaat deze alleen hoeft te luisteren naar een PriceLowered event of zo.

Als je zo'n voorbeeld project kunt uploaden met de basis werking zou ik er graag eens naar kijken om het static gedeelte eruit te halen en meer object oriented maken.
 
@knarfoe Heb drie berichten van je aangepast omdat de code niet tussen de codetags staan. Graag hier aan denken de volgende keer.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan