2009-09-15 11 views
3

Je veux écrire un contrôle similaire à ComboBox et je me demande si quelqu'un sait comment détecter lorsqu'un utilisateur clique en dehors des limites ComboBox. Le ComboBox ferme sa liste déroulante dans cette situation.WPF - Comment Combobox sait quand fermer le menu déroulant

+0

Une question, pourquoi vous voulez écrire votre combo, si vous pouvez personnaliser le combo de wpf comme vous voulez? –

+0

J'ai essayé. Mais le problème est que le clavier ne fonctionne pas pour le contrôle personnalisé à l'intérieur de la combobox. Actuellement, le contrôle personnalisé à l'intérieur de la zone de liste déroulante est un sélecteur de date/heure non géorgien. –

Répondre

2

Vous pouvez définir votre propre modèle de contrôle et de contrôle personnalisé avec une zone de texte et une fenêtre contextuelle. Ensuite, remplacer la méthode OnApplyTemplate de votre commande et trouver le menu contextuel en utilisant:

var popup = this.GetTemplateChild("PART_Popup") as Popup; 

Vous pouvez maintenant décider quand afficher ou masquer la fenêtre en définissant ses propriétés IsOpen true ou false.

Pour savoir si un utilisateur clique sur une autre partie de vous UI suffit de souscrire à l'événement PreviewMouseDown sur le parent de votre contrôle (quelque part dans votre code d'initialisation de commande):

var parent = VisualTreeHelper.GetParent(this) as UIElement; 
if(parent != null) { 
    parent.PreviewMouseDown += MouseDownHandler; 
} 

Maintenant, vous devriez être averti chaque fois un utilisateur clique n'importe où dans le conteneur de votre contrôle. Vous pouvez également utiliser VisualTreeHelper.GetParent (...) récursivement pour accéder à l'élément racine (comme une fenêtre) jusqu'à ce qu'il renvoie une valeur nulle. Le popup ne sera pas dans la même arborescence visuelle et vous devez donc définir des gestionnaires d'événements souris pour l'élément racine du popup si vous voulez savoir quand un utilisateur clique dans le popup.

2

J'ai eu la même question il y a plusieurs années avec une version antérieure de Silverlight. J'ai examiné le modèle de contrôle et décompilé le code Microsoft pour constater qu'ils utilisaient une superposition invisible sur toute la fenêtre pour détecter les clics. La comboBox WPF ne semble pas fonctionner de la même manière, mais vous pouvez suivre le modèle Silverlight.

Vous devez créer un rectangle de la même taille que votre fenêtre. Je fais cela en utilisant un RowSpan pour couvrir la grille principale qui contient toute mon application. Vous pouvez également lier la hauteur/largeur à la hauteur/largeur de la fenêtre. Il y a une douzaine de façons de le faire, il suffit de le faire pour remplir toute la fenêtre. Donnez au rectangle une couleur de remplissage de blanc et une opacité de 0. Il a besoin d'une couleur de remplissage pour fonctionner, mais avec Opacité = 0 l'utilisateur ne le verra pas. Pour le débogage, vous pouvez lui donner Red et Opacity .25.

<Rectangle x:Name="fullScreenOverlay" Grid.RowSpan="3" Opacity="0" Fill="White" Visibility="Collapsed" MouseDown="FullScreenOverlay_OnMouseDown" /> 

Un élément clé de c'est de mettre le rectangle en bas de votre XAML afin qu'elle rend au-dessus de tout autre contrôle XAML.

Lorsque vous ouvrez votre contrôle ComboBox like, définissez ce rectangle sur Visible afin qu'il puisse détecter les clics/MouseDown.

private void NotificationButton_Click(object sender, RoutedEventArgs e) 
{ 
    fullScreenOverlay.Visibility = Visibility.Visible; 
    notificationPopup.Visibility = Visibility.Visible; 
} 

Lorsque vous détectez un clic, définissez le rectangle de retour à effondrées et fermer votre ComboBox comme pop-up. Terminé.

private void FullScreenOverlay_OnMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    fullScreenOverlay.Visibility = Visibility.Collapsed; 
    notificationPopup.Visibility = Visibility.Collapsed; 
} 

Cela ne détectera pas les clics qui se produisent en dehors de votre application comme le fait Microsoft ComboBox. Il ne détectera que les clics dans l'application. Mais franchement, je le préfère de toute façon.

Questions connexes