2010-08-25 6 views
2

J'ai une boucle:Event Handlers synchronisation

List<FrameworkElement> list; 
public void Foo(object sender, PrintPageEventArgs e) 
{ 
    foreach(FrameworkElement fe in list) 
    { 
    fe.LayoutUpdated += FeLayoutUpdated; 
    fe.UpdateLayout(); 
    } 
    if(counter >= lista.Count) 
    e.PageVisual = objectFromClass. // was DoSth() 
} 
int counter = 0; 
void FeLayoutUpdated(object sender, EventArgs e) 
{ 
    counter++ 
} 

donc j'ai besoin DoSth() pour être tiré toujours quand Foo() est tiré et quand tous les objets de la liste FrameworkElement aura son mise à jour. J'essayais d'utiliser une classe Thread et aussi BackgroundWorker, mais je n'arrivais pas à atteindre le comportement désiré, c'est-à-dire que le thread principal attend que fe.UpdateLayout termine ses jobs. J'espère avoir clarifié l'idée principale. Merci pour les réponses.

Répondre

1

Une solution rapide pour se déplacer après le code dans le gestionnaire d'événements tels que

void FeLayoutUpdated(object sender, EventArgs e) 
{ 
    counter++; 
    if(counter >= lista.Count) 
    DoSth(); 
} 
+0

Notez qu'il n'y a aucune garantie que 'LayoutUpdated' ne se déclenche qu'une seule fois par' FrameworkElement' – AnthonyWJones

+0

My bad. Je viens de mettre à jour le code. Comme vous pouvez le voir, je ne peux pas déplacer DoSth() vers le gestionnaire d'événements. –

+0

Je suppose qu'au lieu d'un simple compteur, vous devez suivre si chaque élément a été mis à jour ou non mais cela ne fonctionnera pas non plus car vous ne souhaitez capturer que le dernier événement LayoutUpdated. Quoi qu'il en soit, l'expéditeur sera également nul, donc le suivi des éléments mis à jour serait difficile. – VinayC

1

Y at-il une raison pour laquelle ceci: -

public void Foo(List<FrameworkElement> list) 
{ 
    foreach(FrameworkElement fe in list) 
    { 
    fe.UpdateLayout(); 
    } 
    DoSth(); 
} 

ne fonctionne pas pour vous? (Notez que Foo doit être appelé sur le thread principal de l'interface utilisateur).

+0

Oui, il y a. UpdateLayout - afaik - est asynchrone. Donc avant DoSth() je dois être sûr que tous les éléments de la liste ont des mises à jour mises à jour et par exemple mettre à jour la disposition de DataGrid avec beaucoup de lignes prend plus de temps, donc DoSth() sera déclenché avant que le DataGrid termine sa mise à jour. –

+0

@Michal: Qu'est-ce qui vous fait penser que 'UpdateLayout' est asynchrone? –

+0

Hm ... liste (dans mon cas de test) contient deux DataGrids (je les appelle PrintGrids), qui sont placés sur un contrôle, qui n'est pas affiché à un utilisateur. L'utilisateur voit d'autres DataGrids (VisibleGrids) avec des données qui seront imprimées. Quand il appuie sur 'Imprimer', les PrintGrids sont alimentés avec des données de VisibleGrids. Je dois donc demander à DataGrid.UpdateLayout de demander à DataGrid de s'actualiser. Et quand je le fais dans le dessus, je reçois sur une feuille imprimée un DataGrid avec des données et l'autre sans, donc je pense que le second ne finit pas de rafraichir avant d'être envoyé à l'imprimante. –