[Wpf] Auswählen eines ListBoxItem, wenn seine innere ComboBox fokussiert ist


Answers

Ich habe eine Lösung für dein Problem gefunden.

Das Problem ist, dass das ListBoxItem nicht ausgewählt wird, wenn Sie ein Steuerelement auf Ihrem Listboxitem haben und wenn auf das Steuerelement geklickt wird (wie für das Eingeben von Text oder das Ändern des Werts einer Combobox).

das sollte den Job machen:

public class FocusableListBox : ListBox
{
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return (item is FocusableListBoxItem);
    }

    protected override System.Windows.DependencyObject GetContainerForItemOverride()
    {
        return new FocusableListBoxItem();
    }
}

-> Verwenden Sie diese FocusableListBox anstelle der Standard ListBox von WPF.

Und benutze dieses ListBoxItem:

public class FocusableListBoxItem : ListBoxItem
{
    public FocusableListBoxItem()
    {
        GotFocus += new RoutedEventHandler(FocusableListBoxItem_GotFocus);
    }


    void FocusableListBoxItem_GotFocus(object sender, RoutedEventArgs e)
    {
        object obj = ParentListBox.ItemContainerGenerator.ItemFromContainer(this);
        ParentListBox.SelectedItem = obj;
    }

    private ListBox ParentListBox
    {
        get
        {
            return (ItemsControl.ItemsControlFromItemContainer(this) as ListBox);
        }
    }

}

Eine Treeview hat dieses Problem auch, aber diese Lösung funktioniert nicht für eine Treeview , weil SelectedItem of Treeview ist. Also wenn du mir bitte mit der Treeview helfen kannst ;-)

Question

Ich habe ein DataTemplate, das ein ListBoxItem-Template sein wird, dieses DataTemplate hat eine ComboBox, die, wenn es den Fokus hat, das ListBoxItem, das diese Vorlage darstellt, ausgewählt werden soll, das sieht für mich richtig aus. aber leider funktioniert es nicht = (

Die eigentliche Frage ist hier in einem DataTemplate ist es möglich, den Wert der ListBoxItem.IsSelected Eigenschaft über einen DataTemplate.Trigger zu erhalten oder zu setzen?

<DataTemplate x:Key="myDataTemplate" 
              DataType="{x:Type local:myTemplateItem}">

 <Grid x:Name="_LayoutRoot">
     <ComboBox x:Name="testComboBox" />
 </Grid>

 <DataTemplate.Triggers>
     <Trigger Property="IsFocused" value="true" SourceName="testComboBox">
         <Setter Property="ListBoxItem.IsSelected" Value="true" />
     </Trigger>
 </DataTemplate.Triggers>

</DataTemplate>

<ListBox ItemTemplate="{StaticResource myDataTemplate}" />



Ich fand, dass ich es vorzog, dies zu verwenden:

<Style  TargetType="ListBoxItem">
    <Style.Triggers>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
             <Setter Property="IsSelected" Value="True"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

Einfach und funktioniert für alle Listboxitems, unabhängig davon, was drin ist.




Keine Ahnung, warum dein Auslöser nicht funktioniert. Um das Get-Fokus-Ereignis des Kombinationsfelds (oder eines beliebigen Steuerelements innerhalb eines Listenfeldelements) abzufangen, können Sie angehängte Routingereignisse verwenden. Sie könnten den Code auch in eine abgeleitete Listbox einfügen, wenn Sie dieses Verhalten in anderen Teilen Ihrer Anwendung benötigen.

XAML:

<Window x:Class="RoutedEventDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Specialized="clr-namespace:System.Collections.Specialized;assembly=System"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Height="300" Width="300">

    <Window.Resources>

        <DataTemplate x:Key="myDataTemplate">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding}" Margin="5,0"/>
                    <ComboBox Width="50">
                        <ComboBoxItem>AAA</ComboBoxItem>
                        <ComboBoxItem>BBB</ComboBoxItem>
                    </ComboBox>
                </StackPanel>
            </Grid>
        </DataTemplate>

    </Window.Resources>

    <Grid>

        <ListBox ItemTemplate="{StaticResource myDataTemplate}">
            <ListBox.ItemsSource>
                <Specialized:StringCollection>
                    <System:String>Item 1</System:String>
                    <System:String>Item 2</System:String>
                    <System:String>Item 3</System:String> 
                </Specialized:StringCollection>
            </ListBox.ItemsSource>
        </ListBox>

    </Grid>
</Window>

Code, der sich an alle anschloss, bekam Fokus-Events.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace RoutedEventDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            EventManager.RegisterClassHandler(typeof(UIElement),
                                              GotFocusEvent,
                                              new RoutedEventHandler(OnGotFocus));
        }

        private static void OnGotFocus(object sender, RoutedEventArgs e)
        {
            // Check if element that got focus is contained by a listboxitem and
            // in that case selected the listboxitem.

            DependencyObject parent = e.OriginalSource as DependencyObject;
            while (parent != null)
            {
                ListBoxItem clickedOnItem = parent as ListBoxItem;
                if (clickedOnItem != null)
                {
                    clickedOnItem.IsSelected = true;
                    return;
                }

                parent = VisualTreeHelper.GetParent(parent);
            }
        }
    }
}