Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Έχω μια εφαρμογή chat το UI τρέχει στο main thread και έχω ένα thread που θέλω να γράψει σε ένα textbox του UI αλλα όταν πάω να γράψω στον debugger βλέπω πως άλλαξε το text αλλά στο UI δεν έχει αλλάξει εκτός αν βάλω στην εξωτερική κλάση την showDialog() τοτε εμφανίζει νέο παράθυρο με το κείμενο μέσα στο textbox, ενώ εγώ θέλω να γύνετε αυτόματα. Έχω διαβάσει πολύ πράμα στο stack overflow και στο msdn αλλά δεν μπόρεσα να βγάλω άκρη, διάβασα για delegates, dispatchers και invoke αλλά δεν κατάφερα να λύσω το πρόβλημα μου.

 

εξωτερική κλάση κώδικας που τρέχει σε function του thread

Form2 form2 = new Form2();   // I assume you set this somewhere
         
        
        public void UpdateTextBox(String text) {
            form2.setText("test");  
        }

UI thread main κλάση

public delegate void changeTextboxHandler();
        public event changeTextboxHandler changed;

        public Form2() {
            InitializeComponent();
        }

        public void Form2_Load() {

        }
        protected virtual void OnNumChanged() {
            if(changed != null) {
                changed();
            }
            else {
                Console.WriteLine("Event fired!");
            }
        }

        public void setText(String text) {
            textBox1.Text = text;
        }
Δημοσ.

Όπως διάβασες, αυτό που θέλεις δε γίνεται "απευθείας" και θα χρειαστεί (Begin)Invoke.

 

Δεν μπορείς να βγάλεις άκρη αλλά δε μας δείχνεις και τι δοκίμασες να βοηθήσουμε. Το copy paste είναι το πιο εύκολο πράγμα στον κόσμο και ορίστε, αλλά αν δεν καταλάβεις τι παίζει αύριο πάλι το ίδιο θέμα θα έχεις.

 

public void UpdateTextBox(String text)
{
    if (form2.InvokeRequired)
    {
     form2.BeginInvoke(new Action(() => form2.setText("test")));
    }
    else
    {
     form2.setText("test"); 
    }
}
  • Like 1
Δημοσ.

Την μέθοδο που ποσταρες την βάζω στην κλάση του ui και την καλώ από άλλο thread που τρέχει σε άλλη κλάση, δημιουργώ ένα instance της φόρμας μου στην εξωτερική κλάση και κάνω την κλήση. Συμβαίνει το ίδιο η αλλαγή στο textbox γίνετε αλλά άμα δεν κάνω showDialog δεν το εμφανίζει και ανοίγει καινούριο form.

Δημοσ.

Πώς γίνεται να τη βάζεις στην κλάση του UI όταν στο πρώτο μήνυμα λες "εξωτερική κλάση κώδικας που τρέχει σε function του thread"; Προφανώς και γω γι' αυτό επέλεξα εκείνη τη method κι όχι άλλη.

 

Το άλλο που λες για ShowDialog και άνοιγμα καινούριου form απλά δεν το καταλαβαίνω αλλά τελείως γενικά, άμα δεν έχεις μπλοκάρει το UI thread με κάτι άλλο (δηλαδή αν τρέχει κανονικά το message pump και όχι δικός σου κώδικας που αργεί πολύ) δεν παίζει να έχεις τέτοια προβλήματα.

 

Και ξανά, κάτσε να διαβάσεις να καταλάβεις τι παίζεται.

Δημοσ.

Που εχεις φτιαξει την φορμα σου; στο δευτερο thread;

 

Η λογικη ειναι πολυ απλη. Το main thread φτιαχνει ενα δευτερο thread στο οποιο θα κανεις πασα το reference της φορμας. Στο δευτερο thread, ολες οι κλεισεις στη φορμα, θα γινονται με BeginInvoke.

 

Αυτο ηταν.

 

Βεβαια στην νεα c# εχεις Task await async που κρυβουν ολη αυτη την μακαροναδα με τα threads πχ

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            using (var wc = new WebClient())
            {
                var data = await wc.DownloadDataTaskAsync("http://www.insomnia.gr/uploads/profile/photo-thumb-216584.jpg?_r=1384551814");
                this.pictureBox1.Image = Image.FromStream(new MemoryStream(data));
            }
        }
    }
}

Δημοσ.

Μήπως χρειάζεται refresh...τα GUI...το θέλουν καμία φορά.

 

Άμα δεν πιάσει αυτό να κάνει και κανα reboot μετά καλού κακού;  :rolleyes:

  • Like 2
Δημοσ.

 

έχω ένα thread που θέλω να γράψει σε ένα textbox του UI αλλα όταν πάω να γράψω στον debugger βλέπω πως άλλαξε το text αλλά στο UI δεν έχει αλλάξει εκτός αν βάλω στην εξωτερική κλάση την showDialog() τοτε εμφανίζει νέο παράθυρο με το κείμενο μέσα στο textbox,

Κοίτα βάσει αυτού κάπου έγραψε αυτό που ήθελε. Γιατί δεν εμφανίζεται; Είναι γραμμένο σε νέο αντικείμενο; Είναι γραμμένο εκεί που πρέπει και δεν έχει κάνει ShowDialog;

Ύστερα δείχνει ένα UpdateText και ένα event OnNumChanged????

Δημοσ.

Κρίνοντας από την (τεχνικά ελλιπέστατη) περιγραφή, πιθανότατα γιατί με κάτι απ' όλα αυτά που κάνει κρατάει απασχολημένο το UI thread αντί να το αφήσει να τρέξει message loop όπως είναι το πεπρωμένο του. Αλλά αυτό δεν έχει καμία σημασία.

 

What I'm saying is, η γνωστή σου συνήθεια. Μπορεί να μην έχεις ιδέα τι γίνεται αλλά κάτι θα βρεις να προτείνεις. Κόψτην, κάνει κακό και σε σένα που δε θα μάθεις να προσεγγίζεις το θέμα μεθοδικά και σε όσους αποφασίσουν να ακολουθήσουν τις προτροπές σου.

  • Like 1
Δημοσ.

Decouple the fuck

namespace WindowsFormsApplication1
{
    using System;
    using System.Threading;
    using System.Windows.Forms;
    using System.Threading.Tasks;

    public partial class Form1 : Form
    {
        private Worker worker_ = new Worker();

        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            try {
                await worker_.DoWorkAsync(
                    new Progress<string>(_ => label1.Text = _));
            } catch (OperationCanceledException) {
                label1.Text = "Work cancelled";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            worker_.CancelWork();
        }
    }

    internal class Worker
    {
        private CancellationTokenSource cts_;

        public Task DoWorkAsync(IProgress<string> pg)
        {
            if (pg == null) {
                throw new ArgumentNullException(nameof(pg));
            }

            if (cts_ != null) {
                return Task.FromResult(0);
            }

            cts_ = new CancellationTokenSource();

            return Task.Run(async () => {
                for (; {
                    cts_.Token.ThrowIfCancellationRequested();
                    // work work work work work work
                    pg.Report(Environment.WorkingSet.ToString());
                    await Task.Delay(500, cts_.Token);
                }
            });
        }

        public void CancelWork()
        {
            cts_?.Cancel();
            cts_?.Dispose();
            cts_ = null;
        }
    }
}

  • Like 1
Δημοσ.

Defacer,

Μια ιδέα σκέφτηκα, μπορεί να είναι λάθος. Δεν επιτρέπονται τα λάθη;

 

Στο θέμα τώρα. Θέλει να κατεβάσει μια εικόνα και όσο το κάνει η φόρμα είναι απασχολημένη, και μάλλον δεν έχει φορτώσει το text box. Θα μπορούσε να ξεκίνησει το κατέβασμα αφού είχε φορτώσει όλα τα στοιχεία και την εικόνα που θέλει την φορτώνει μετά, ενώ βάζει κάτι πρόχειρο στη θέση της.

Δημοσ.

Defacer,

Μια ιδέα σκέφτηκα, μπορεί να είναι λάθος. Δεν επιτρέπονται τα λάθη;

 

Εσύ λες "σκέφτηκα". Εγώ θα το έλεγα "δεν κατάλαβα ούτε το context ούτε το πρόβλημα αλλά ορίστε τι πιστεύω". We've been there before. Το να κάνεις λάθος διάγνωση όντας γιατρός είναι λάθος. Το να κάνεις διάγνωση ενώ δεν είσαι γιατρός δεν ξέρω πως θες να το πεις, αλλά μάλλον δεν είναι "λάθος".

Δημοσ.

Δεν αντιλαμβάνομαι το μάθημα!

Αυτή την εποχή  φτιάχνω το GUI της Μ2000, και δεν ξέρω ποιος άλλος εδώ έχει φτιάξει δικά του windows....Όταν φτιάχνεις κάτι τέτοιο  καταλαβαίνεις πέρα από τα βασικά. Δες τελευταίο παράδειγμα στο Blog μου, κώδικας που δεν γίνεται compile, και όμως φτιάχνει δυναμικά παράθυρα.

Π.χ όταν ένα στοιχείο περάσει πίσω μια μεταβλητή έστω για να δει κανείς τι θα γραφτεί σε ένα Textbox και να αλλαχτεί πριν αυτό το εμφανίσει (δηλαδή πληκτρολογούμε και η αλλαγή δίνεται για έλεγχο), τότε το μήνυμα πρέπει να πάει άμεσα για διεκπεραίωση. Όμως σε άλλες περιπτώσεις που δεν έχουμε απαίτηση για άμεση επιστροφή τιμής (δεν περνάει By reference) θέλουμε να πάει σε ένα σωρό. σε κάτι όπου θα το πάρει με τη σειρά του κάποιο νήμα, κάτι που δουλεύει ασύγχρονα. Αυτά λοιπόν εσύ μπορεί να τα έχεις χρησιμοποιήσει..αλλά δεν τα έχεις φτιάξει! Οπότε μην μου την λες ως ο ειδικός. Νομίζεις ότι κάνω χαζές ερωτήσεις; Κάνεις λάθος. Κάνω τέτοιες που δεν τις σκέφτεσαι καν. Ο καθένας έχει το τρόπο που σκέφτεται και ό,τι δεν μας φαίνεται οικείο, δυστυχώς κάποιοι το εκμεταλλεύονται για να σπάνε τη πλάκα τους.

Τι ήταν τόσο σημαντικό για να με "βάλεις" στη θέση μου; Τίποτα! Απλά δεν καταλαβαίνεις ότι έχεις μια Grootϊαση...όταν δεν μπορείς με ευκολία να προσπεράσεις ότι δεν σου αρέσει! Αν ήμασταν όλοι έτσι θα είχαμε σκοτωθεί για ψύλλου πήδημα!

Δημοσ.

Ας πούμε ότι ήταν λάθος μου να νομίζω ότι θα έκανε κάποια διαφορά να το πω άλλη μια φορά. Έχεις φτιάξει δικά σου windows και καταλαβαίνεις πέρα από τα βασικά, sure.

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...