I Une zone de liste wpf affiche une liste de zones de texte. Lorsque je clique sur la zone de texte, la sélection de la zone de liste ne change pas. Je dois cliquer à côté de la zone de texte pour sélectionner l'élément de zone de liste. Y at-il une propriété que je dois définir pour la zone de texte pour transférer l'événement click à la zone de liste?La sélection d'un élément de zone de texte dans une zone de liste ne modifie pas l'élément sélectionné de la zone de liste
Répondre
La zone de liste gère la sélection d'élément mais ne connaît pas le focus de la zone de texte incorporée. Si vous voulez changer la sélection à chaque fois qu'une zone de texte reçoit le focus d'entrée, vous devez changer manuellement la sélection de la zone de liste, afaik.
Y a-t-il une propriété que je dois définir pour que Textbox transfère l'événement click dans la Listbox?
Ce n'est pas une simple propriété, mais vous pouvez gérer l'événement GotFocus
sur votre TextBox
, puis utilisez VisualTreeHelper pour trouver le ListBoxItem
et sélectionnez:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox myTextBox = sender as TextBox;
DependencyObject parent = VisualTreeHelper.GetParent(myTextBox);
while (!(parent is ListBoxItem))
{
parent = VisualTreeHelper.GetParent(parent);
}
ListBoxItem myListBoxItem = parent as ListBoxItem;
myListBoxItem.IsSelected = true;
}
Je ne suis pas tout à fait sûr que vous voulez pour définir la sélection directement comme décrit dans la réponse précédente, car je pense que cela casserait multiselection et d'autres scenerios
. Vous pouvez essayer de restyler un bouton comme ci-dessous et voir ce qui se passe.
<Button ClickMode="Pressed" Focusable="False">
<Button.Template>
<ControlTemplate> // change the template to get rid of all the default chrome
<Border Background="Transparent"> // Button won't be clickable without some kind of background set
<ContentPresenter />
</Border>
</ControlTemplate>
</Button.Template>
<TextBox />
Votre pas très précis sur votre situation initiale. Mais je suppose que vous utilisez DataBinding et un ItemTemplate. C'est un moyen facile de le faire, aussi bien que votre débutant sur ce sujet. Cela devrait fonctionner:
<ListBox ItemsSource="{Binding someDataCollection}" Name="myListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding datafield}" Tag="{Binding .}"
GotFocus="TextBox_GotFocus"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
myListBox.SelectedItem = (sender as TextBox).Tag; /* Maybe you need to cast to the type of the objects contained in the collection(bound as ItemSource above) */
}
La façon la plus simple que je suis en mesure de trouver pour ce faire est d'utiliser l'événement PreviewMouseDown et définissez la propriété IsSelected du parent basé sur un modèle. Puisque les événements de prévisualisation descendent en bulle, le ListBoxItem traite l'événement dès que l'utilisateur clique sur la zone de texte, la zone de liste déroulante ou tout autre contrôle sur lequel vous avez défini l'événement. Une bonne chose à propos de ceci est que vous pouvez utiliser le même événement pour tous les types de contrôles, car ils dérivent tous de l'élément Framework. En outre, si vous définissez IsSelected (au lieu de définir SelectedItem), plusieurs éléments seront sélectionnés lorsque vous définissez le paramètre SelectionMode de la zone de liste sur "Extended", ce qui peut ou ne peut pas être ce que vous recherchez.
-à-dire:
C# Code
private void Element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
((sender as FrameworkElement).TemplatedParent as ListBoxItem).IsSelected = true;
}
XAML
...
<ComboBox PreviewMouseDown="Element_PreviewMouseDown"/>
<TextBox PreviewMouseDown="Element_PreviewMouseDown"/>
...
Nous utilisons le style suivant pour définir une PreviewGotKeyboardFocus qui gère tous les événements de contrôle TextBox et ComboBoxes et tels:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
</ListView.ItemContainerStyle>
Et puis nous sélectionnons la ligne dans le code derrière:
protected void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
ListViewItem item = (ListViewItem) sender;
item.IsSelected = true;
}
c'est la réponse que vous cherchez: Selecting a ListBoxItem when its inner ComboBox is focused
+1 pour pointer vers d'autres solutions intéressantes. – rotti2
je similaire à la solution de Robert, mais sans code derrière (en utilisant le comportement ci-joint).
Pour ce faire,
d'abord. Créer une classe distincte FocusBehaviour:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyBehaviours
{
public class FocusBehaviour
{
#region IsFocused
public static bool GetIsFocused(Control control)
{
return (bool) control.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(Control control, bool value)
{
control.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusBehaviour),
new UIPropertyMetadata(false, IsFocusedPropertyChanged));
public static void IsFocusedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as Control;
if (control == null || !(e.NewValue is bool))
return;
if ((bool)e.NewValue && !(bool)e.OldValue)
control.Focus();
}
#endregion IsFocused
#region IsListBoxItemSelected
public static bool GetIsListBoxItemSelected(Control control)
{
return (bool) control.GetValue(IsListBoxItemSelectedProperty);
}
public static void SetIsListBoxItemSelected(Control control, bool value)
{
control.SetValue(IsListBoxItemSelectedProperty, value);
}
public static readonly DependencyProperty IsListBoxItemSelectedProperty = DependencyProperty.RegisterAttached(
"IsListBoxItemSelected",
typeof(bool),
typeof(FocusBehaviour),
new UIPropertyMetadata(false, IsListBoxItemSelectedPropertyChanged));
public static void IsListBoxItemSelectedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as Control;
DependencyObject p = control;
while (p != null && !(p is ListBoxItem))
{
p = VisualTreeHelper.GetParent(p);
}
if (p == null)
return;
((ListBoxItem)p).IsSelected = (bool)e.NewValue;
}
#endregion IsListBoxItemSelected
}
}
Deuxième. Ajouter un style dans la section des ressources (mon style est arrondi en noir). Notification setter pour la propriété FocusBehaviour.IsListBoxItemSelected. Vous devez faire référence dans xmlns:behave="clr-namespace:MyBehaviours"
`
<Style x:Key="PreviewTextBox" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border
Margin="6,2,0,4"
BorderBrush="#FFBDBEBD"
BorderThickness="1"
CornerRadius="8"
Background="White"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MinWidth="100"
x:Name="bg">
<ScrollViewer
x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Background" TargetName="bg" Value="Black"/>
<Setter Property="Background" Value="Black"/><!-- we need it for caret, it is black on black elsewise -->
<Setter Property="Foreground" Value="White"/>
<Setter Property="behave:FocusBehaviour.IsListBoxItemSelected" Value="True"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
`
troisième. (facultatif, pour la tâche inverse)
Vous rencontrerez, sinon aucune, la tâche inverse - se concentrant sur TextBox lorsque ListBoxItem est sélectionné. Je recommande d'utiliser une autre propriété de la classe Behavior, IsFocused. Voici un exemple de modèle pour ListBoxItem
, s'il vous plaît notez Property="behave:FocusBehaviour.IsFocused"
et FocusManager.IsFocusScope="True"
<DataTemplate x:Key="YourKey" DataType="{x:Type YourType}">
<Border
Background="#FFF7F3F7"
BorderBrush="#FFBDBEBD"
BorderThickness="0,0,0,1"
FocusManager.IsFocusScope="True"
x:Name="bd"
MinHeight="40">
<TextBox
x:Name="textBox"
Style="{StaticResource PreviewTextBox}"
Text="{Binding Value}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding IsSelected,RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
<Setter
TargetName="textBox"
Property="behave:FocusBehaviour.IsFocused"
Value="True" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
-je utiliser un gestionnaire de classe pour définir ce comportement. Le faire de cette façon permettra de corriger toutes les vues de la liste dans l'application. Je ne sais pas pourquoi ce n'est pas le comportement par défaut.
Dans votre App.xaml.cs, ajoutez ce qui suit à OnStartup:
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof (ListViewItem),
ListViewItem.PreviewGotKeyboardFocusEvent,
new RoutedEventHandler((x,_) => (x as ListViewItem).IsSelected = true));
}
Assurez-vous d'utiliser TargetType approprié: ListViewItem, ListBoxItem ou TreeViewItem.
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="IsSelected" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
Ne fonctionne pas si
Cela pose également le problème que la sélection est supprimée lorsque ListView perd le focus. La réponse ci-dessous est meilleure d'Arcturus –
Essayez ce code:
foreach (object item in this.listBox1.Items) {
if (textbox1.text.equals(item.toString())) {
//show error message; break
}
}
Je n'ai pas assez de représentants pour commenter, donc je suis poster mon commentaire comme réponse. La solution de Grazer ci-dessus ne fonctionne pas dans les cas où vous avez un autre contrôle tel qu'un Button
qui nécessite le SelectedItem
. C'est parce que selon le Style Trigger
, le IsKeyboardFocusWithin
devient faux lorsque vous cliquez sur ce Button
, et le SelectedItem
devient nul.
Old discussion, mais peut-être ma réponse aide les autres ....
solution de Ben a le même problème que la solution de Grazer. La mauvaise chose est que la sélection dépend du focus [clavier] de la zone de texte. Si vous avez un autre contrôle sur votre boîte de dialogue (c'est-à-dire sur un bouton), le focus est perdu lorsque vous cliquez sur le bouton et l'élément listbox devient non sélectionné (SelectedItem == null). Vous avez donc un comportement différent pour cliquer sur l'élément (en dehors de la zone de texte) et cliquer dans la zone de texte. C'est très fastidieux à manipuler et ça a l'air très étrange.
Je suis assez sûr qu'il n'y a pas de solution XAML pure pour cela. Nous avons besoin de code-behind pour cela. La solution est proche de ce que Mark a suggéré.
(dans mon exemple j'utilise ListViewItem au lieu de ListBoxItem, mais la solution fonctionne pour les deux).
code-behind:
private void Element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var frameworkElement = sender as FrameworkElement;
if (frameworkElement != null)
{
var item = FindParent<ListViewItem>(frameworkElement);
if (item != null)
item.IsSelected = true;
}
}
avec FindParent (prise de http://www.infragistics.com/community/blogs/blagunas/archive/2013/05/29/find-the-parent-control-of-a-specific-type-in-wpf-and-silverlight.aspx):
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
return FindParent<T>(parentObject);
}
Dans mon DataTemplate:
<TextBox Text="{Binding Name}"
PreviewMouseDown="Element_PreviewMouseDown"/>
Ce qui suit est une simplification de @ la réponse de Ben sans avoir à remplacer le DataTemplate. Il peut même être appliqué en tant que style statique. Testé avec un ListView contenant un GridView > GridViewColumn > TextBox
.
Exemple:
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
- 1. Supprimer un élément d'une zone de liste quitte la zone de liste sans élément sélectionné
- 2. La sélection d'un élément dans une zone de liste
- 3. Définir l'élément sélectionné dans une zone de liste de données
- 4. ASP.NET Afficher les éléments sélectionnés de la zone de liste dans la zone de texte
- 5. Suivi d'un élément dans la zone de liste
- 6. Implémenter une zone de liste
- 7. Sélection d'éléments dans une zone de liste en utilisant C#
- 8. Animer un élément supprimé dans la zone de liste
- 9. Menu contextuel de la zone de liste
- 10. Problème de sélection multiple dans une zone de liste
- 11. La sélection d'un élément dans une zone de liste (asp.net 3.5)
- 12. Surlignage d'un élément particulier dans une zone de liste déroulante
- 13. comment modifier la valeur dans la zone de texte à la date actuelle en fonction de la valeur sélectionnée dans la zone de liste déroulante dans javascript
- 14. Auto remplir une zone de liste déroulante
- 15. Événements de zone de liste déroulante VB6
- 16. Problème de zone de liste asp.net
- 17. Ajustement de la largeur de la liste déroulante de remplissage automatique dans une zone de texte
- 18. Silverlight 3 Zone de liste
- 19. est-il possible d'avoir différentes couleurs de texte dans une zone de texte ou une zone de liste?
- 20. zone de liste déroulante Lier (JQuery préférence)
- 21. Comment définir la couleur d'arrière-plan d'un widget comme une zone de liste déroulante ou une double zone de sélection?
- 22. Flex: Modification de la zone de texte
- 23. Ajouter un élément au-dessus de la zone de texte sans modifier la position de la zone de texte
- 24. Ne pas autoriser le zéro dans la zone de texte
- 25. Enregistrement du dernier élément sélectionné sur une zone de liste déroulante
- 26. changeant la couleur sélectionnée iTMS dans une zone de liste
- 27. Sélection de points géographiques dans la zone
- 28. WPF zone de liste déroulante en surbrillance
- 29. lier des données dans la zone de liste
- 30. Comment styliser une zone de liste déroulante?
Cela semble sans aucun doute la meilleure méthode. J'ai une hiérarchie profondément imbriquée, ListBoxes contenues dans d'autres ListBox, et divers contrôles contenus à l'intérieur de ceux-ci. Cette méthode fonctionne simplement, car elle utilise uniquement le ListBoxItem et non le contrôle contenu. Un changement suggéré cependant - il est plus simple de simplement sélectionner l'élément directement: item.IsSelected = true – Niall
Excellente suggestion! J'ai changé le code .. – Arcturus
Grazer a une meilleure réponse ci-dessous – Amsakanna