6
votes

Comment afficher un message occupé sur un écran WPF

Hey, J'ai une application WPF basée sur le prisme4. Lorsque vous effectuez des opérations lentes, je souhaite montrer un écran occupé. J'aurai un grand nombre d'écrans, alors j'essaie de construire une solution unique dans le cadre plutôt que d'ajouter l'indicateur occupé à chaque écran.

Ces longues opérations de course fonctionnent dans un fil d'arrière-plan. Cela permet de mettre à jour l'interface utilisateur (bon) mais n'arrête pas l'utilisateur de l'utilisation de l'interface utilisateur (mauvais). Ce que j'aimerais faire, c'est superposer un contrôle avec une sorte de chose de cadran de filage et que ce contrôle couvre l'écran entier (l'ancien tour HTML avec DIV). Lorsque l'application est occupée, le contrôle afficherait donc une interaction supplémentaire ainsi que montrer la chose épinée.

Pour le mettre en place, je pensais que je pouvais simplement avoir mon écran d'application dans une toile avec la truc Spinny (avec un plus grand zindex), alors faites simplement la chose qui est visible si nécessaire.

Cela, cependant, devient difficile. Les toiles ne semblent pas bien installées pour cela et je pense que je pourrais aboyer le mauvais arbre.

J'apprécierais toute aide. Merci.


3 commentaires

Voir ma réponse pour une manière plus simple lorsque vous souhaitez empêcher l'interaction avec l'application entière


@MarkMnl et où est votre réponse?


@TheIncrediblejan Stackoverflow.com/a/4505932/349528 J'espère que c'est valable!


3 Réponses :


14
votes

Je l'ai fait avec quelques programmes. Ici, c'est en un mot:

(c'est le plus facile avec MVVM. Cela fait si longtemps que j'ai utilisé le codeBehid pour des choses comme ceci, je ne peux pas vraiment dire s'il y a un bon moyen de le faire.) p>

  1. Créez une bordure sur votre fenêtre principale. Je le rend habituellement noir avec une transparence de 50%. Ajoutez une grille à cela et mettez ce que vous voulez à l'intérieur pour dire aux utilisateurs qu'il est occupé. Taille la bordure et les commandes à l'intérieur pour remplir l'écran. li>
  2. Créez une propriété sur votre point de vue principal pour Isbusy comme Boolean. Initialiser comme faux. Lier la propriété de visibilité de la frontière occupée à cette propriété. Li>
  3. Suivant, faites une classe de convertisseur pour une visibilité occupée (booléenne). Écrivez la logique dans celle de sorte que lorsque la valeur est vraie, la visibilité est visible, lorsque la valeur est fausse, la visibilité est effondrée. ( http://msdn.microsoft.com/en-us/library/system .windows.data.ivalueconverter.aspx ). Li>
  4. Retour à la frontière, ajoutez votre convertisseur à la liaison. Ajoutez du code au point de vue pour chacune de vos pages ou vues qui rappelle à cette propriété et la définit en true lorsque votre autre thread est occupé. Li> ol>

    cory p>

    EDIT: P>

    <Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">
    
    <Grid>
    
        <Border BorderBrush="Black" BorderThickness="1" Background="#80000000" Visibility="Collapsed">
            <Grid>
                <TextBlock Margin="0" TextWrapping="Wrap" Text="Busy...Please Wait" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667" FontWeight="Bold" Foreground="#7EFFFFFF"/>
            </Grid>
        </Border>
    
        <DockPanel x:Name="LayoutRoot">
            <CheckBox Content="CheckBox" VerticalAlignment="Top"/>
            <TextBlock TextWrapping="Wrap"><Run Text="TextBlock"/></TextBlock>
            <UserControl x:Name="ViewViewView"/>
        </DockPanel>
    </Grid>
    


4 commentaires

Merci Cory. Le problème que j'ai (ou mon cerveau faible) est de savoir comment configurer le contrôle afin qu'il chevauche le contrôle principal de l'application. J'ai actuellement ma fenêtre principale avec un dockpanel à l'intérieur. Je ne peux pas simplement ajouter une bordure à l'intérieur (la teneur en fenêtre ne peut être définie qu'une seule fois) afin que je dois utiliser un panneau pour contenir les deux. L'évidence à utiliser est la toile, mais il est moins amusant d'utiliser. Long et court: comment puis-je établir mon contrôle d'attente et mon contrôle d'application dans votre étape 1?


Le panneau de quai est le plus grand conteneur? Dans ce cas, je mettrais le dockpanel dans une grille et le faire remplir complètement la grille. La frontière peut alors s'asseoir sur le dockpanel. J'utilise presque toujours une grille comme conteneur de niveau supérieur. J'ai constaté que cela me permettait beaucoup plus de flexibilité avec où je peux placer des articles et comment ils interagissent avec le reste du contenu Windows. J'ai ajouté un petit code ci-dessus pour montrer un exemple.


J'utilise une approche similaire pour les superpositions occupées dans une grille - j'ai dû utiliser le zindex cependant pour les faire toujours apparaître sur le dessus.


Merci Cory, c'est ce que j'étais après.



0
votes

Je fais cela en affichant simplement une boîte de dialogue (l'utilisateur ne peut donc pas interagir avec quoi que ce soit d'autre et il sera affiché sur le dessus) puis gérer l'événement de fermeture (comme l'utilisateur pouvait appuyer sur Alt-F4) pour voir si l'opération est terminée. Sinon, j'annule l'événement de clôture:

myWaitWindow.ShowDialog(); // this can be borderless window with a spinny thing


void Window_Closing(object sender, CancelEventArgs e)
{
  if(this.myOperation.IsRunning)  // you would have to have some way to see when your operation has finished
    e.Cancel = true;
}


0 commentaires

3
votes

Regardez cette boîte à outils WPF avec un indicateur occupé: https://github.com/xcedesoftware / WPfoToolkit / Wiki / Bushindicator


0 commentaires