2010-05-31 10 views
3

Mon application a la configuration de l'interface utilisateur suivante:formes enfants lents à tirer mdi lorsque la visibilité changé

La principale forme est un conteneur MDI. Ses formes enfant sont attachées à un TabStrip.

Chaque utilisateur a son jeu de formulaires enfants. En fonction de l'utilisateur actif, seuls les formulaires enfants de cet utilisateur sont affichés, ainsi que les onglets. Ceci est obtenu en passant par le MdiChildren du formulaire principal et en définissant leur propriété Visible sur false/true en fonction de l'utilisateur actif.

 foreach (Form item in MdiChildren) 
     { 
      if (((OfficeFormEx)item).UserID == (int)e.NewTab.Tag) 
      { 
       item.Visible = true; 
      } 
      else 
      { 
       item.Visible = false; 
      } 
     } 

Cela a deux effets indésirables. L'un est que chaque forme d'enfant est redessinée successivement, ce qui est laid et lent. L'autre est que, pour une raison ou une autre, les formes vont de maximisées à normales, les désanchant effectivement de la forme principale.

Y a-t-il un moyen d'afficher uniquement l'un des formulaires enfant, tel que celui que l'utilisateur regardait précédemment, et de laisser les autres rester en arrière-plan? Le maximum/normal n'est pas un gros problème parce que je peux les maximiser manuellement.

+0

+1 Votre question a été posée pour apprendre quelque chose que @Hans Passant a clairement expliqué. Merci! =) –

Répondre

1

J'ai finalement résolu celui-ci, donc voici une description tardive.

Will Marcouiller a suggéré SuspendLayout() et ResumeLayout(), qui ne fonctionnait pas. Cela m'a conduit à étudier ce que ces deux méthodes font réellement et à conclure que ce dont j'avais besoin était un moyen d'empêcher le redessin du formulaire principal pendant que les opérations sur les enfants MDI étaient en cours. Ceci à son tour a abouti aux deux méthodes d'utilitaire statique suivantes qui suspendent le redessin pour un contrôle donné. Dans mon cas, suspendre le redessin de la forme principale a entraîné une accélération massive.

/// <summary> 
/// suspends drawing on a control and its children 
/// </summary> 
/// <param name="parent"></param> 
public static void SuspendDrawing(Control control) 
{ 
    SendMessage(control.Handle, WM_SETREDRAW, false, 0); 
} 

/// <summary> 
/// resumes drawing on a control and its children 
/// </summary> 
/// <param name="parent"></param> 
public static void ResumeDrawing(Control control) 
{ 
    SendMessage(control.Handle, WM_SETREDRAW, true, 0); 
    control.Refresh(); 
} 
2

A première vue, je voudrais jeter un oeil à la propriété Form.WindowsState, si ce n'est déjà fait. Je doute que si vous définissez cette propriété à FormWindowState.Maximized sur la conception, cela sera changé lors de la définition de leur propriété Visibletrue/false. Pour la méthode "[...] chaque enfant est redessiné successivement [...]", avez-vous essayé d'utiliser la méthode SuspendLayout() au début de la vérification des formulaires de l'utilisateur actif, puis en appelant ResumeLayout() par la suite ?

EDIT # 1

  • Je vous conseille de ne charger que le Form requis pour l'utilisateur actuel.

Cela permettra de réduire la quantité de mémoire utilisée par votre application, plus, il réduit considérablement le nombre de formes contenues dans la propriété de collection MdiChildren. Ensuite, iterating à travers la collection, si nécessaire, sera plus rapide.

Si ce n'est pas une option pour vous, en utilisant peut-être Linq pourrait aider:

var visibleForms = from f in MdiChildren 
        where (((OfficeFormEx)f).UserID == (int)e.NewTab.Tag) 
        select f; 

var invisibleForms = from f in MdiChildren 
        where (((OfficeFormEx)f).UserID != (int)e.NewTab.Tag) 
        select f 

visibleForms.ToList().ForEach(f => f.Visible = true); 
invisibleForms.ToList().ForEach(f => f.Visible = false); 

Si vous utilisez .NET 4.0, serait peut-il être un bon candidat pour PLINQ

Veuillez fournir vos commentaires afin que nous puissions trouver une solution. =)

+0

Ni aide, malheureusement. – dandan78

+0

Ensuite, afin de nous aider à vous aider, fournissez un exemple de code de ce que vous faites pour vérifier ce que MdiChild rendra visible, etc. Considérer que les applications Mdi n'ont généralement pas tous les MdiChildren possibles chargés et ouverts à début de l'application. Si vous comprenez bien, peut-être laisser l'utilisateur ouvrir ce que MdiChild dont il a besoin serait souhaitable. –

+0

Je viens d'ajouter le code. Dans ce cas, tous les enfants MDI possibles sont chargés à tout moment car chaque utilisateur a un nombre fixe de formulaires utilisés pour afficher diverses parties de l'application. Lorsque l'utilisateur actif change, l'utilisateur n'a besoin de voir que son sous-ensemble de formulaires. – dandan78

2

Votre question n'est pas très claire sans un fragment de code. Vous êtes en train de faire la bataille avec l'implémentation Windows MDI. Une chose qu'il ne supporte pas est de cacher une fenêtre enfant, elle ne peut être minimisée que dans le meilleur des cas. Windows Forms implémente la propriété Visible en détruisant le handle de fenêtre, en le recréant lorsque la propriété Visible est définie sur True à nouveau. Cette nouvelle instance de la fenêtre ne sera pas maximisée.

Il ne supporte pas non plus le passage à une fenêtre enfant lorsque la fenêtre courante est maximisée. La solution de WF pour cela consiste à forcer la fenêtre enfant active à l'état Normal.

Le modèle MDI n'est tout simplement pas très approprié pour afficher des fenêtres enfants dans l'état maximisé. Pour obtenir une interface à onglets, utilisez un TabControl et affichez UserControls sur ses pages à onglet.

+0

Désolé si j'ai omis des détails importants, mais je n'ai vraiment pas vu l'intérêt d'inclure une boucle foreach. :) Le reste de votre commentaire à propos de MDI résume assez bien ce que je suis en train de faire. :(Cependant, je pourrais jurer qu'une partie de cela a fonctionné dans un de mes précédents projets, je vais devoir jeter un coup d'oeil Merci pour l'info sur ce qui se passe sous le capot – dandan78

+0

+1 Ce sont des informations précieuses à considérer lorsqu'il s'agit d'applications MDI. –

Questions connexes