2009-01-30 5 views
6

J'ai une application Silverlight qui a un Canvas. Sur ce canevas, je "peins" dynamiquement un tas de choses, mais en ajoutant des contrôles à la toile.Silverlight: forcer le canevas à s'annuler ou à se repeindre?

J'ai un bouton en dehors de la zone Canvas qui efface le contenu. Les objets sont supprimés (avec succès). Toutefois, la zone Canvas ne s'actualise pas immédiatement; il nécessite actuellement un événement MouseOver ou autre pour le canevas lui-même.

Quelle est la manière la plus simple d'avoir un objet externe invalide un canevas? Je suis sûr qu'il me manque quelque chose de simple!

Répondre

4

Il est un peu sale, mais vous pouvez essayer de changer la visibilité de « visible » (même si elle est déjà) de la toile, donc:

myCanvas.Visibility = Visibility.Visible; 

Nous avons constaté que ces forces comme redessiner, même si la valeur réelle de myCanvas.Visible n'a pas changé ...

Essayez-le, c'est seulement un revêtement qui peut arranger les choses. Bien que je m'attendrais à ce que la toile soit redessinée de toute façon si vous en supprimez des choses.

+0

D'une manière ou d'une autre, mon problème s'est résolu. Cependant, cette réponse est excellente, car elle a un très faible impact. Je vais probablement ajouter ceci à mon code comme une mesure défensive. – pearcewg

1

Dans le cas où quelqu'un vient après le fait que je ne cherche cette réponse ...

yourFrameworkElement.InvalidateArrange(); 
yourFrameworkElement.UpdateLayout(); 

a fonctionné pour moi.

Remarque: l'appel seulement this.yourFrameworkElement.UpdateLayout(); a fait pas travailler pour moi. J'ai dû appeler le InvalidateArrange(). J'ai immédiatement appelé UpdateLayout() pour la complétude - a probablement zéro impact réel.

L'astuce myCanvas.Visibility = Visibility.Visible; ne fonctionnait pas pour moi car j'essayais de déclencher l'événement LayoutUpdated.

+0

N'a pas causé de repeindre pour moi. Cela semble ne pas être une solution à ce problème. – Brett

1

Pas un simple doublure, mais cela fonctionne. Cela fonctionne bien dans mon expérience. Il reporte l'action donnée pendant un dixième de seconde pour permettre la mise à jour du thread de l'interface utilisateur, mais exécute toujours l'action sur le thread de l'interface utilisateur.

using System; 
using System.Windows.Threading; 

public static class MyTestClass 
{ 
    public static void Postpone(Action a_action) 
    { 
     TaggedDispatchTimer timer = new TaggedDispatchTimer(); 
     timer.Interval = TimeSpan.FromSeconds(0.1); 
     timer.Tick += OnDoPostponedAction; 
     timer.UserState = a_action; 
     timer.Start(); 
    } 

    private static void OnDoPostponedAction(object sender, EventArgs e) 
    { 
     TaggedDispatchTimer timer = sender as TaggedDispatchTimer; 
     timer.Stop(); 
     timer.Tick -= OnDoPostponedAction; 

     var action = timer.UserState as Action; 
     if (action != null) 
      action(); 
    } 
} 

public class TaggedDispatchTimer : DispatcherTimer 
{ 
    public Object UserState { get; set; } 

} 

Voilà comment je l'utilise:

MyTestClass.Postpone(() => 
    { 
     // Do some bloody long operation. 
    }); 
0

Dans mon cas (j'avais une toile dans une toile et je avais besoin de redimensionner la toile intérieure en raison d'un changement d'orientation), la myCanvas.Visibility = Visibility.Visible; astuce didn ne le fais pas, mais il était vraiment proche:

myCanvas.Visibility = Visibility.Collapsed; 
myCanvas.Visibility = Visibility.Visible; 

a travaillé très bien.

Le InvalidateArrange suivi d'un UpdateLayout ne l'a pas non plus fait. À la fin, tout cela n'était pas nécessaire, car je me suis rendu compte que le Canevas à l'intérieur d'un Canevas n'était pas nécessaire et pouvait changer le Canevas interne pour un StackPanel, et aucun truc n'était nécessaire pour qu'il fonctionne comme prévu .

Questions connexes