Ich habe eine WPF-Listbox, die eine Liste von Textfeldern anzeigt. Wenn ich auf die Textbox klicke, ändert sich die Listbox-Auswahl nicht. Ich muss neben dem Textfeld klicken, um den Listeneintrag auszuwählen. Gibt es eine Eigenschaft, die ich für das Textfeld festlegen muss, um das Klickereignis an die Listbox weiterzuleiten?Auswählen eines Textboxelements in einer Listbox ändert nicht das ausgewählte Element der Listbox
Antwort
Die Listbox behandelt die Elementauswahl, kennt aber nicht den Fokus der darin eingebetteten Textbox. Wenn Sie die Auswahl jedes Mal ändern möchten, wenn ein Textfeld den Eingabefokus erhält, müssen Sie die Listenfeldauswahl manuell ändern, afaik.
Gibt es eine Eigenschaft ich für die Textbox festlegen muß das Click-Ereignis auf das Listenfeld zu übermitteln?
Es ist keine einfache Eigenschaft, aber Sie können die GotFocus
Ereignis auf Ihrem TextBox
, dann VisualTreeHelper die ListBoxItem
und wählen Sie sie finden verwenden Griff:
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;
}
ich nicht ganz sicher bin, würden Sie wollen, die Auswahl direkt zu setzen, wie in der vorherigen Antwort beschrieben, weil ich denke, es brechen würde Mehrfachauswahl und einige andere scenerios
. Sie können versuchen, eine Schaltfläche wie unten neu zu formatieren und zu sehen, was passiert.
<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 />
Ihre nicht sehr spezifisch über Ihre Ausgangssituation. Aber ich nehme an, dass Sie DataBinding und ein ItemTemplate verwenden. Thats imho eine einfache Möglichkeit, dies zu tun, auch wenn Ihr Anfänger zu diesem Thema. Dies sollte funktionieren:
<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) */
}
Der einfachste Weg, ich habe in der Lage gewesen zu finden, dies zu tun ist, um das Preview Ereignis zu verwenden und die IsSelected Eigenschaft der Templat-Eltern festgelegt. Da die Vorschau-Ereignisse nach unten blubbern, verarbeitet das ListBoxItem das Ereignis, sobald der Benutzer auf das Textfeld, die Combobox oder ein anderes Steuerelement klickt, auf dem Sie das Ereignis festlegen.
Eine schöne daran ist, dass Sie das gleiche Ereignis für alle Arten von Kontrollen verwenden können, da sie alle aus Rahmenelement abzuleiten. Wenn Sie IsSelected (statt SelectedItem) setzen, werden auch mehrere Elemente ausgewählt, wenn Sie den SelectionMode des Listenfelds auf "Extended" setzen, was das sein könnte, was Sie suchen.
dh:
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"/>
...
Wir verwenden die folgenden Stil eine PreviewGotKeyboardFocus zu setzen, die alle Ereignisse von TextBox Steuergriffe und Comboboxen und so:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
</ListView.ItemContainerStyle>
Und dann wählen wir die Zeile im Code hinter:
protected void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
ListViewItem item = (ListViewItem) sender;
item.IsSelected = true;
}
das ist die Antwort, die Sie suchen: Selecting a ListBoxItem when its inner ComboBox is focused
+1 für das Zeigen auf andere interessante Lösungen. – rotti2
ich ähnlich wie Robert-Lösung verwendet, aber ohne Code hinter (mit beiliegendem Verhalten).
Um dies zu tun,
Zuerst. Erstellen Sie separate Klasse 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
}
}
Sekunde. Fügen Sie einen Stil im Ressourcenbereich hinzu (mein Stil ist im Fokus schwarz gerundet). Benachrichtigungssetter für die FocusBehaviour.IsListBoxItemSelected-Eigenschaft. Sie sollten darauf verweisen in 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>
`
Dritter. (optional, für umgekehrte Aufgabe)
Sie werden, wenn nicht, eine Reverse-Aufgabe treffen - Fokussierung auf TextBox, wenn ListBoxItem ausgewählt wird. Ich empfehle, eine andere Eigenschaft der Verhaltensklasse IsFokussiert zu verwenden. Hier ist eine Beispielvorlage für ListBoxItem
, beachten Sie bitte Property="behave:FocusBehaviour.IsFocused"
und 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>
ich eine Klasse Handler dieses Verhalten einzustellen. Auf diese Weise werden alle Listenansichten in der Anwendung korrigiert. Ich weiß nicht, warum das nicht das Standardverhalten ist. Folgendes OnStartup
In Ihrem App.xaml.cs hinzu:
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof (ListViewItem),
ListViewItem.PreviewGotKeyboardFocusEvent,
new RoutedEventHandler((x,_) => (x as ListViewItem).IsSelected = true));
}
Achten Sie darauf, geeignete Target zu verwenden: ListViewItem, ListBoxItem oder TreeViewItem.
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="IsSelected" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
Funktioniert nicht, wenn
Dies hat auch das Problem, dass die Auswahl entfernt wird, wenn der ListView den Fokus verliert. Die Antwort unten ist besser von Arcturus –
Versuchen Sie diesen Code:
foreach (object item in this.listBox1.Items) {
if (textbox1.text.equals(item.toString())) {
//show error message; break
}
}
ich nicht kommentieren genug Wiederholungen müssen, so dass ich meinen Kommentar als Antwort veröffentlichen. Die obige Grazer-Lösung funktioniert nicht in Fällen, in denen Sie ein anderes Steuerelement haben, z. B. Button
, das SelectedItem
benötigt. Dies liegt daran, dass gemäß Style Trigger
die IsKeyboardFocusWithin
falsch wird, wenn Sie auf Button
klicken, und die SelectedItem
wird null.
alte Diskussion, aber vielleicht meine Antwort hilft anderen ....
Ben-Lösung hat das gleiche Problem wie Grazers Lösung. Das Schlimme ist, dass die Auswahl vom [Tastatur-] Fokus der Textbox abhängt. Wenn Sie ein anderes Steuerelement in Ihrem Dialogfeld haben (z. B. eine Schaltfläche), geht der Fokus verloren, wenn Sie auf die Schaltfläche klicken, und das Listenfeld wird nicht ausgewählt (SelectedItem == null). Sie haben also ein anderes Verhalten, wenn Sie auf das Element (außerhalb des Textfelds) klicken und in das Textfeld klicken. Dies ist sehr mühsam zu handhaben und sieht sehr seltsam aus.
Ich bin mir ziemlich sicher, dass es dafür keine reine XAML-Lösung gibt. Dafür brauchen wir Code-Behind. Die Lösung kommt dem nahe, was Mark vorgeschlagen hat.
(in meinem Beispiel verwende ich ListViewItem statt ListBoxItem, aber die Lösung funktioniert für beide).
-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;
}
}
mit FindParent (aus 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);
}
In meinem Datatemplate:
<TextBox Text="{Binding Name}"
PreviewMouseDown="Element_PreviewMouseDown"/>
Das Folgende ist eine Vereinfachung der @ Ben Antwort ohne das DataTemplate zu überschreiben. Es kann sogar als statischer Stil angewendet werden. Getestet mit einer ListView, die eine GridView > GridViewColumn > TextBox
enthält.
Beispiel:
<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. ListBox Ausgewählte Textfarbe
- 2. Wie setze ich das ausgewählte Item einer Listbox in WP7?
- 3. Concatenate ListBox ausgewählte Artikel
- 4. Mehrere ListBox-Elemente in derselben ListBox mit einem Klick auswählen
- 5. Listbox-Steuerelement OwnerDraw-Frage (Hinzufügen eines Bearbeitungssteuerelements zum Listbox-Element)
- 6. Ausgewähltes Element in der Listbox anzeigen
- 7. Listbox Ausgewählte Eigenschaft verursacht Probleme
- 8. Preset Listbox Element Auswahl
- 9. Rahmen ausgewählte Element auf Listbox in Silverlight - Windows Phone 7
- 10. Hol dir das ListBoxItem in einer ListBox
- 11. Listbox Auswahl-Handler in GWT
- 12. Mouseover zum Auswählen von Element in Listbox in WPF
- 13. Wie Sie das ausgewählte Element in der Listbox auf der Ansicht
- 14. Verwenden jedes Element in einer Listbox
- 15. ListBox Element entfernen
- 16. Get ausgewähltes Element der ListBox mit ContextMenu
- 17. Verfolgen eines Elements in Listbox
- 18. WPF ListBox Button Ausgewähltes Element
- 19. In Javascript, wie Listbox-Element (von HTML) aus einer Listbox, die möglicherweise nicht vorhanden ist
- 20. Anordnen einer Silverlight-Listbox - MVVM-stylee
- 21. Bindungsmodus für Element in Listbox
- 22. ListBox SystemColor für inaktives Element?
- 23. Ausgewähltes Element in einer ListBox ohne Schleife einstellen
- 24. Integrieren eines Trennzeichens in Listbox
- 25. Übertragen Sie mehrere ausgewählte Objekte von ListBox zu einer anderen ListBox
- 26. Zeige textarea, wenn das ausgewählte Element in der Listbox geändert wird
- 27. Auswählen von Elementen in einer Listbox mit C#
- 28. jquery bekomme alle Werte in einer Listbox Listbox und Indexiere eine Listbox
- 29. Wie man ein ausgewähltes Element von einer listBox zu einer anderen listBox hinzufügt
- 30. MouseLeftButtonDown wird von einer ListBox nicht erkannt?
Dies scheint auf jeden Fall die beste Methode. Ich habe eine tief verschachtelte Hierarchie, ListBoxen, die in anderen ListBoxen enthalten sind, und verschiedene Steuerelemente, die in diesen enthalten sind. Diese Methode funktioniert nur, weil sie nur das ListBoxItem und nicht das enthaltene Steuerelement verwendet. Eine vorgeschlagene Änderung obwohl - es ist einfacher, den Artikel direkt auszuwählen: item.IsSelected = true – Niall
Ausgezeichneter Vorschlag! Ich habe den Code geändert .. – Arcturus
Grazer hat eine bessere Antwort unter – Amsakanna