Выбор ListBoxItem, когда его внутренний ComboBox сфокусирован
У меня есть DataTemplate, который будет шаблоном ListBoxItem, этот DataTemplate имеет
ComboBox, в котором, когда он имеет фокус, я хочу, чтобы ListBoxItem этот шаблон
представляет, чтобы стать избранным, это выглядит правильно для меня. но, к сожалению, это не работает = (
Итак, реальный вопрос здесь находится в DataTemplate, возможно ли получить или установить значение
свойства ListBoxItem.IsSelected
через DataTemplate.Trigger
?
<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}" />
Ответы
Ответ 1
Я нашел решение для вашей проблемы.
Проблема заключается в том, что когда у вас есть элемент управления в вашем элементе listboxitem, и элемент управления щелкнут (например, для ввода текста или изменения значения combobox), ListBoxItem не будет выбран.
это должно выполнить задание:
public class FocusableListBox : ListBox
{
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is FocusableListBoxItem);
}
protected override System.Windows.DependencyObject GetContainerForItemOverride()
{
return new FocusableListBoxItem();
}
}
- > Используйте этот FocusableListBox вместо списка ListBox по умолчанию WPF.
И используйте этот 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);
}
}
}
A Treeview
также имеет эту проблему, но это решение не работает для a Treeview
, потому что SelectedItem
of Treeview
есть readonly
.
Поэтому, если вы можете помочь мне с Treeview, пожалуйста, -)
Ответ 2
Я обнаружил, что предпочитаю использовать это:
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
Простой и работает для всех элементов listbox, независимо от того, что внутри.
Ответ 3
Не знаю, почему ваш триггер не работает. Чтобы поймать событие получения фокуса в поле со списком (или любой элемент управления внутри элемента списка), вы можете использовать связанные перенаправленные события. Вы также можете поместить код в производный список, если вам нужно это поведение в других частях вашего приложения.
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>
Код за привязкой ко всем полученным событиям фокуса.
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);
}
}
}
}