Par fenêtre-pop-up, je veux dire un popup qui reste en quelque sorte avec une fenêtre/application. Pour autant que je sais que je vais devoir gérer explicitement montrer/cacher de pop-up basée sur
Application.Current.Activated/Désactivé
Application.Current.MainWindow.Activated/Désactivé
ParentWindow.Activated/Désactivé
I vous voulez vous assurer que Alt-Tab cache/affiche le popup, win-D cache popup, basculer entre les fenêtres de la même application ne devrait rien faire, la restauration/maximisation depuis la barre des tâches devrait afficher popup. J'ai des gestionnaires écrits pour tous ces événements, et ils me tuent, pourquoi est-ce un problème si irritant. Il doit y avoir un moyen simple de gérer cela. Des idées?WPF la création de fenêtre-popup
2
A
Répondre
1
Un gestionnaire d'événement unique devrait suffire pour l'ensemble du travail.
d'abord dans votre App.xaml ajouter un style de fenêtre qui définit le gestionnaire d'événements en utilisant une propriété attachée:
<Style TargetType="Window">
<Setter Property="local:PopupWindowControl.AttachHandler" Value="true" />
</Style>
Mark toutes vos fenêtres qui ont besoin du comportement spécial:
<Window local:PopupWindowControl.HideWhenAppInactive="true" ... >
maintenant vous avez juste besoin de créer les propriétés attachées et une méthode de mise à jour
- "HideWhenAppInactive" est un bool att propriété douloureuse utilisée pour marquer Windows et Popups. Il maintient également un enregistrement de tous les Popups avec cet ensemble de propriétés. "AttachHandler" est une propriété jointe à un booléen avec un PropertyChangedCallback qui attache le gestionnaire.
- « Mise à jour » est une méthode qui met à jour la visibilité de Windows et popups basée sur l'existence d'une & visible fenêtre active
Il ressemblerait à quelque chose comme ceci:
public class PopupWindowControl : DependencyObject
{
// HideWhenAppInactive
public static bool GetHideWhenAppInactive(DependencyObject obj) { return (bool)obj.GetValue(HideWhenAppInactiveProperty); }
public static void SetHideWhenAppInactive(DependencyObject obj, bool value) { obj.SetValue(HideWhenAppInactiveProperty, value); }
public static readonly DependencyProperty HideWhenAppInactiveProperty = DependencyProperty.RegisterAttached("HideWhenAppInactive", typeof(bool), typeof(PopupWindowControl), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
if((bool)e.NewValue && obj is Popup)
{
if((_cleanupCounter++ % 10000) == 0)
_hideWhenInactivePopups = (from weakRef in _hideWhenInactivePopups where weakRef.IsAlive select weakRef).ToList();
_hideWhenInactivePopups.Add(new WeakReference(obj));
}
}
});
// AttachHandler
public static bool GetAttachHandler(DependencyObject obj) { return (bool)obj.GetValue(AttachHandlerProperty); }
public static void SetAttachHandler(DependencyObject obj, bool value) { obj.SetValue(AttachHandlerProperty, value); }
public static readonly DependencyProperty AttachHandlerProperty = DependencyProperty.RegisterAttached("AttachHandler", typeof(bool), typeof(PopupWindowControl), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
if((bool)e.NewValue)
{
var window = (Window)obj;
window.Activated += Update;
window.Deactivated += Update;
window.StateChanged += Update;
}
}
});
private static void Update(object sender, EventArgs e)
{
var active =
Application.Current.Windows.OfType<Window>().Where(win =>
win.IsActive &&
win.Visibility==Visibility.Visible &&
win.WindowState != WindowState.Minimized)
.Any();
// First update Windows marked HideWhenAppInactive
foreach(var popupWindow in Application.Current.Windows.OfType<Window>().Where(win => GetHideWhenAppInactive(win)))
popupWindow.Visibility = active ? Visibility.Visible : Visibility.Hidden;
// Then update Popups marked HideWhenAppInactive
if(active && _temporarilyHiddenPopups!=null)
{
foreach(var popup in _temporarilyHiddenPopups)
popup.IsOpen = true;
_temporarilyHiddenPopups = null;
}
else if(!active)
{
if(_temporarilyHiddenPopups==null) _temporarilyHiddenPopups = new List<Popup>();
foreach(var popup in
(from weak in _hideWhenInactivePopups
let popup = weak.Target as Popup
where popup!=null && popup.IsOpen && GetHideWhenAppInactive(popup)
select popup))
{
_temporarilyHiddenPopups.Add(popup);
popup.IsOpen = false;
}
}
}
private static List<WeakReference> _hideWhenInactivePopups = new List<WeakReference>();
private static List<Popup> _temporarilyHiddenPopups;
private static int _cleanupCounter;
}
Notez que je n'a pas ajouté de code pour détacher le gestionnaire lorsque "AttachHandler" ou "HideWhenAppInactive" sont définis sur false car, à cette fin, ils ne seront jamais utilisés de cette façon.
Questions connexes
- 1. Création de ListView dans WPF?
- 2. Création de fichiers WPF C#
- 3. WPF Création d'événements personnalisés
- 4. Création de l'objet de la fenêtre WPF à l'exécution
- 5. WPF Grille de création de tables
- 6. Création de WPF par rapport à Visual Studio Création
- 7. Outil de création de diagrammes pour WPF
- 8. WPF Architecture & Création unique Builds
- 9. Création d'une instance WPF InlineCollection
- 10. MVVM WPF Création d'éléments enfants
- 11. Création de raccourcis clavier «globaux» dans WPF
- 12. Création d'animations de haute performance dans WPF
- 13. Création de contrôle dynamique dans WPF
- 14. Création de formulaires personnalisés dans WPF?
- 15. Création du contrôle d'exécution WPF
- 16. Création d'une grille de propriétés WPF?
- 17. Tutoriel WPF pour la création d'un contrôle utilisateur personnalisé
- 18. Différence dans la création d'objet Application dans WPF et WinForms
- 19. Création d'un arrière-plan transparent dans WPF
- 20. Création d'une interface utilisateur personnalisée dans WPF
- 21. WPF Création d'un ControlTemplate qui est DataBound
- 22. Création manuelle d'un cube WPF 3D
- 23. Bonnes pratiques de création de contrôles personnalisés composites WPF
- 24. Création dynamique de formulaires WPF à l'aide de fichiers XAML
- 25. Création d'une fenêtre WPF à partir de l'invite de commande
- 26. Options de création de rapports pour une application WPF?
- 27. Création d'un contrôle d'édition de code source complexe dans WPF
- 28. Bibliothèque pour la création de présentations animées
- 29. Création d'une apparence de fenêtre commune dans WPF
- 30. Aucune création de fenêtre WPF dans un projet DLL?
J'ai essayé votre code, mais il a ces questions: 1. cacher/en cliquant sur Taskbar n'invoque pas mise à jour - j'ajouté événement StateChanged pour cette 2. Dans la mise à jour vous changez la visibilité de la fenêtre, je besoin de changer la visibilité (propriété IsOpen) de popup sur une fenêtre. –
Traiter avec Popup.IsOpen est un jeu d'enfant puisque vous avez enregistré l'état précédent de IsOpen. J'ai ajouté le code pour le faire, ainsi que le gestionnaire StateChanged. –
Eh bien ... comme je l'ai dit je peux le faire fonctionner en manipulant tous ces événements, j'espérais obtenir une solution simple à ce problème .. Je suis sûr qu'il y a beaucoup de gens qui ont besoin de cette fonctionnalité. –