IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

FlowDocument Image & Thread


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2009
    Messages : 7
    Par défaut FlowDocument Image & Thread
    Bonjour,

    Y a t-il un moyen ou une astuce pour créer un Flowdocument contenant des images dans un thread séparé. Le problème étant que pour ajouter une image dans un FlowDocument il faille utiliser un System.Windows.Controls.Image, et que celui ci ne peut être utilisé que dans le UI Thread. A l'heure actuelle mon interface est figée le temps de la création du document ce qui n'est pas top.

  2. #2
    Membre émérite Avatar de obito
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2008
    Messages
    773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2008
    Messages : 773
    Par défaut
    salut,

    Bon voila une piste pour réaliser ce que tu souhaite :

    1. Supposons que l'image s'ajoute sur le clic d'un bouton :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private void Button1_Click(object sender, RoutedEventArgs e)
    {
     
        Thread th1 = new Thread(new ThreadStart(test));
        th1.Start();
        th1.Join();
    }

    2. Ensuite il faut créer le void test :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    private void test()
    {
     
                this.Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)delegate
                {
                    //ton traitement...             
                });
    }

    Dans le délégate de Test tu n'a plus qu'à ajouter l'image à ton Flow Document.

    Je te conseil, pour comprendre ce code, de te renseigner sur le Dispatcher. Il existe une explication ici :

    http://www.switchonthecode.com/tutor...wpf-dispatcher

    Mais ce n'est pas la seule.

  3. #3
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2009
    Messages : 7
    Par défaut
    Merci mais ta solution fonctionne seulement si l'objet FlowDocument appartient au Thread UI.
    Je doit produire un rapport a partir d'informations extraites d'une base de donnée (images comprises), cela peut prendre beaucoup de temps c'est pourquoi je souhaite faire le travail en tache de fond.
    Il n'y a pas de problème tant que l'on utilise pas d'objet graphique.
    Voici comment j'ai fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
        private void ReportWorker_DoWork(object sender, DoWorkEventArgs e)
        {
          try
          {
            BackgroundWorker worker = sender as BackgroundWorker;
            Object[] p = (Object[])e.Argument;
            string filename = p[0] as string;
            FlowDocument doc = new FlowDocument();
            // Construit le document
            BuildReport(filename,doc);
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            XamlWriter.Save(doc, stream);
            stream.Position = 0;
            // Mettre a jour l'interface graphique
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,
                         (Action)delegate
                         {
                           Report = (FlowDocument)XamlReader.Load(stream);
                         });
     
          }
          catch (Exception ex)
          {
             ...
          }
        }
    Le problème intervient dès que je veut ajouter une image dans BuildReport().
    L'objet image ne peut être crée que par le thread UI.
    Et on ne peut pas passer/utiliser un objet graphique entre les 2 threads.
    Si je n'avais qu'une seule image encore je pourrai l'ajouter depuis le thread UI
    mais je peux en avoir beaucoup.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Par défaut
    Salut,

    Pourtant le BackgrounWorker me semblait une bonne idée.

    Dans l'évènement ProgressChanged et RunWorkerCompleted, tu peux jouer avec l'interface. Comme dans l'exemple suivant :
    http://msdn.microsoft.com/fr-fr/libr...8VS.95%29.aspx

    A voir...

  5. #5
    Membre émérite Avatar de obito
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2008
    Messages
    773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2008
    Messages : 773
    Par défaut
    Voila ma deuxième solution aurait été le BackgroundWorker. Voici par exemple, un programme qui génère 100 usercontrol (assez lourd) en tache d fond grâce au backgroundWorker :

    Dans le Loaded :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     BackgroundWorker worker = new BackgroundWorker();
     worker.DoWork+=new DoWorkEventHandler(traitement);
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.WorkerReportsProgress = true;
    worker.RunWorkerAsync();

    Dans traitement :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    private void traitement(object s, DoWorkEventArgs args)
    {
                double i = 1;
                foreach (IndicateurViewModel o in mwm.IndicateursVM)
                {
                    this.Dispatcher.Invoke(DispatcherPriority.Background, (ThreadStart)delegate
                    {
                        Indicateur ind = new Indicateur();
                        ind.DataContext = o;
                        p.Children.Add(ind);
                        worker.ReportProgress((int)((i / mwm.IndicateursVM.Count) * 100));
                        i++;
                    });
                }
     
    }

    J'epargne le code du progressChanged qui n'a guère d'interêt dans ton problème. Dans ce code, tout se fait donc en tache de fond avec même une progressBar qui indique la progression... Voila j'espère que ca pourra t'aider un peu

  6. #6
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2009
    Messages : 7
    Par défaut
    Faire le travail par le ProgressChanged permet de créer l'objet Image mais comme il est interdit de le copier dans dans le FlowDocument qui n'est pas dans le threadUI, cela ne résout pas le problème.

    Ajouter les images dans le document depuis le RunWorkerCompleted est toujours possible mais pas très logique et comme je peux en avoir beaucoup, mon interface va être quand même bloquée.

    Quand a la solution de obito c'est ce que j'utilise pour afficher les éléments de ma table dans l'interface graphique et ca marche très bien, le problème vient du FlowDocument et des objet graphiques que l'on veut mettre dedans. L'objet graphique doit être créé dans le thread UI et c'est la que je bloque. La seule solution semble être de crée le FlowDocument dans le thread UI et du coup mon interface est figée pendant quelques secondes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Windows Phone 7] Isolated Storage, Images et Thread
    Par rolandl dans le forum Windows Phone
    Réponses: 1
    Dernier message: 02/05/2013, 23h53
  2. [Prbl] Thread(image ne s'affichant pas avant le thread.sleep
    Par stephane92400 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 26/06/2006, 11h57
  3. thread d'alternance d'images
    Par orphenou dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 12/12/2005, 12h03
  4. Charger une image dans un thread
    Par KRis dans le forum Langage
    Réponses: 3
    Dernier message: 25/08/2005, 17h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo