Comment puis-je éviter le scintillement dans une application en plein écran WPF?
J'ai une application WPF qui est un plein écran kiosque app. C'est en fait une assez compliqué d'application à ce moment, mais voici un code qui indique l'idée de base. Essentiellement, chaque fois que l'utilisateur passe d'un écran à l'autre, il y a un peu de sérieux scintillement d'aller sur la mise en place de la nouvelle fenêtre. Dans les cas graves, le bureau s'affiche pendant quelques secondes avant que le nouvel écran s'affiche. Qui n'a pas lieu dans cet exemple de code, parce que c'est tellement simple, mais ajouter un peu plus de boutons et de styles, et vous le verrez.
App.xaml.cs:
public partial class App : Application {
Manager mManager;
public App() {
mManager = new Manager();
Window1 screen1 = new Window1(mManager);
mManager.Screen1 = screen1;
try {
this.Run(screen1);
} catch (Exception e) {
System.Console.WriteLine(e.ToString());
} finally {
Application.Current.Shutdown();
}
}
}
Window1.xaml.cs:
public partial class Window1 : Window {
Manager Manager{get; set;}
public Window1(Manager inManager) {
InitializeComponent();
Manager = inManager;
}
private void OnChangeScreen(object sender, RoutedEventArgs e) {
Manager.OpenScreen2();
}
}
Window2.xaml.cs:
public partial class Window2 : Window {
Manager Manager{get; set;}
public Window2(Manager inManager) {
InitializeComponent();
Manager = inManager;
}
private void OnChangeScreen(object sender, RoutedEventArgs e) {
Manager.OpenScreen1();
}
}
Manager.cs:
public class Manager {
public Window1 Screen1{ get; set;}
public Window2 Screen2{ get; set;}
public Manager(){
Screen1 = new Window1(this);
}
public void OpenScreen2() {
Screen2 = new Window2(this);
Screen2.Show();
if (Screen1 != null) {
Screen1.Hide();
}
}
public void OpenScreen1() {
Screen1 = new Window1(this);
Screen1.Show();
if (Screen2 != null) {
Screen2.Hide();
}
}
}
Window1.xaml (essentiellement imité par window2.xaml):
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
WindowStyle="None"
WindowState="Maximized"
Width="1280"
Height="1024"
FontFamily="Global User Interface"
ResizeMode="NoResize">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Name="ChangeScreenButton" Click="OnChangeScreen" Grid.Row="2" Grid.Column="2" Content="Toggle Screen 2"></Button>
</Grid>
</Window>
L'entrelacement de l'affiche des deux fenêtres (c'est à dire, montrer la fenêtre 1 avant la suppression de la fenêtre 2, etc) ne change pas le scintillement de comportement. Dans cette simple application, il serait possible de simplement masquer les autres écrans qui ne sont pas indiquées, mais en plus compliqué d'application, il n'y a tout simplement trop d'informations d'état pour gérer les informations de l'écran facilement et correctement.
Est-il un peu de magie, un mot de code ou de la technique pour éviter le scintillement qui serait à l'œuvre dans cette application simple qui s'adapte aussi à l'application plus complexe? Je suis inquiet que je vais être obligée de réécrire l'intégralité de l'INTERFACE utilisateur à ce stade pour soutenir le masquage et l'affichage, et c'est juste pas possible dans mon calendrier.
EDIT: j'ai essayé de la cacher/montrer des chose sur certaines boîtes de dialogue, et il ne semble pas à la matière. Peut-être que c'est parce que le principal kiosque app est un style lourd?
source d'informationauteur mmr
Vous devez vous connecter pour publier un commentaire.
La cause sous-jacente de le scintillement est qu'à chaque fois que vous .Hide() une fenêtre de son
PresentationSource
est déconnecté, provoquantUnloaded
événements à feu sur tout et tout mis en cache dans leMILCore
couche de WPF à être jetés. Puis, quand vous.Show()
plus tard, tout est reconstruit.Pour éviter le scintillement, assurez-vous de garder votre INTERFACE utilisateur connecté à un PresentationSource à tout moment. Cela peut être fait de plusieurs façons:
Seule fenêtre avec déguisé TabControl
Utiliser une seule fenêtre contenant un
TabControl
de style de sorte que vous ne pouvez pas voir les onglets. Changer d'onglet dans le code lorsque vous le feriez normalement d'afficher ou de masquer les fenêtres. Vous pouvez simplement rechercher-remplacer "Fenêtre" dans votre code existant par "Page", puis remplacer "Afficher()" appelle à votre custom "Afficher()" qui effectue les opérations suivantes:La ContentTemplate vous pouvez utiliser pour votre TabControl est extrêmement simple:
À l'aide d'un Cadre de Navigation
À l'aide de
Frame
avec la Navigation est une très bonne solution pour un kiosque parce qu'il met en œuvre beaucoup de changement de page et d'autres fonctionnalités. Cependant, il peut être plus de travail pour mettre à jour une application existante de cette façon plutôt que d'utiliser un TabControl. Dans les deux cas, vous devez convertirWindow
àPage
mais avec l'Image que vous aussi besoin pour faire face à la navigation.Plusieurs fenêtres avec une opacité
Vous pouvez faire une fenêtre presque complètement invisible à l'aide d'une faible opacité et pourtant WPF sera toujours garder l'arborescence visuelle autour de. Ce serait un banal changement: il suffit de remplacer tous les appels à
Window.Show()
etWindow.Hide()
avec des appels à "MyHide()" et "MyShow()" qui met à jour l'opacité. Notez que vous pouvez améliorer encore plus loin en ayant ces routines de déclencher des animations de très courte durée (par exemple de 0,2 seconde) qui animent l'opacité. Depuis deux animations seront définies dans le même temps, l'animation va se dérouler en douceur, et il sera fait un joli effet.Je suis curieux de savoir pourquoi vous utilisez plusieurs fenêtres de la même application dans un Kiosque. Vous pouvez facilement mettre tous les contrôles sur la même "Fenêtre" et il suffit de changer la visibilité sur les Panneaux d'affichage différents "écrans". Ce serait certainement empêcher le bureau de être jamais montré, et vous permettra de faire de belles choses comme des transitions en fondu ou de glissement des animations, etc.
WPF a construit dans la fonctionnalité de navigation.
Il suffit de regarder la Cadre et la Page de classes que vous pouvez facilement concevoir à l'aide de VS ou d'un Mélange.
D'accord avec les commentaires sur l'utilisation de la built-in fonctionnalité de navigation, mais si vous êtes enfermé dans votre design à ce point, peut-être envisager d'animation de l'opacité de votre windows? Un découvert de 100 ou 200 ms animation de l'Opacité de 1 -> 0 pour les sortants de la fenêtre et 0 -> 1, pour la prochaine fenêtre, pourraient résoudre le problème. Gérer le nettoyage de la sortant de la fenêtre de l'événement sur la table de montage séquentiel.
Voyant que la façon dont WPF utilise DirectX et le Processeur Graphique pour décharger le traitement des éléments de l'écran, l'ordinateur est DirectX et les pilotes sont à jour?
Cory
Si vous avez d'initialisation dans le constructeur qui prend un temps long qui pourrait entraîner un retard et sans scintillement. Vous pouvez essayer d'utiliser une méthode asynchrone ou mettre que l'initialisation sur un thread d'arrière-plan de sorte qu'il ne bloque pas l'apparence de la fenêtre.
Un exemple de quelque chose qui serait la cause d'un retard serait une requête de base de données ou d'une requête de données sur un réseau.
Une expérience rapide serait de désactiver des parties du constructeur dans un lent Fenêtre pour trouver la cause du retard dans l'affichage de la Fenêtre.
Comme répondu plus tôt à l'aide de Cadres/Onglet Contrôles éviter le scintillement pendant les transitions
Si vous ne voulez pas changer votre application et que vous souhaitez supprimer que le scintillement (clignotant de bureau) sur Windows7 ou WindowsVista, vous pouvez optimiser votre windows Visual Effects " réglage 'Ajuster pour la meilleure performance"
Ici est un autre moyen facile qui fonctionne pour moi dans mon kiosque application comme avec un fond noir, inspirée des réponses ci-dessus. Ici, j'ai un "LanguageWindow" qui peut être ouvert depuis n'importe où dans l'application pour changer la langue.
Dans LanguageWindow.xaml (vérifier la WindowState=Réduite):
Dans LanguageWindow.xaml.vb:
Voilà!
(fait avec Visual Studio 2015, .NET Framework 4.6, WPF, VB.net)