Расширитель как ListBoxItem не вызывает выбор
У меня есть ListBox
с ListBoxItem
, используя DataTemplate
, который использует Expander
в качестве своего контейнера. Проблема в том, что Expander
кажется, что есть Click
event (HeaderSite
часть Expander
, если быть точным), и я никогда не получаю SelectedItem
, если я нажимаю на Expander
(но он работает, если вы нажмите на ListBoxItem
).
Любая идея о том, как получить Expander
, чтобы играть красиво с помощью ListBox
?
Здесь упрощенный Xaml, который будет воспроизводить проблему (без необходимости кода):
Изменить обновленный код, чтобы приблизиться к моему фактическому шаблону, но скриншоты по-прежнему из предыдущей версии (проблема такая же - это просто для выяснения проблемы с первым ответом)
<Window x:Class="ListBoxSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock>
<Run Text="Selected Item" />
<Run Text="{Binding ElementName=ListBox, Path=SelectedItem}" />
</TextBlock>
<ListBox x:Name="ListBox">
<ListBoxItem>
<Expander Header="Expandable Stuff 1">
<ListBox>
<ListBoxItem>1.1</ListBoxItem>
<ListBoxItem>1.2</ListBoxItem>
</ListBox>
</Expander>
</ListBoxItem>
<ListBoxItem>
<Expander Header="Expandable Stuff 2">
<ListBox>
<ListBoxItem>2.1</ListBoxItem>
<ListBoxItem>2.2</ListBoxItem>
</ListBox>
</Expander>
</ListBoxItem>
</ListBox>
</StackPanel>
</Window>
Скриншоты предварительно редактируются
Нажав ListBoxItem
, в результате получим SelectedItem
:
![Clicking on <code>ListBoxItem</code> resulting a <code>SelectedItem</code>]()
Нажатие на Expander приводит к обновлению нет SelectedItem
(щелчок на Expander 1 был очевиден пунктиром):
![Clicking on Expander resulting no <code>SelectedItem</code> update]()
Ответы
Ответ 1
Без кода позади вы можете сделать это
<ListBox.ItemContainerStyle>
<Style>
<Style.Triggers>
<EventTrigger RoutedEvent="Control.PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="(Selector.IsSelected)">
<BooleanAnimationUsingKeyFrames Duration="0:0:0">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
Ответ 2
Ну, следующий код, похоже, работает с недостатком (или, может быть, преимуществом), что в каждый момент времени будет выходить только выбранный элемент.
Примените следующие 2 атрибута к вашему 2 Expander
s
IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}"
IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}"
Связывая IsHitTestVisible
, а также позволяет взаимодействовать с элементами, содержащимися в Expander
.
Результат:
<ListBox x:Name="ListBox" IsSynchronizedWithCurrentItem="True">
<ListBoxItem>
<Expander Header="Expandable Stuff 1" IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
1
</Expander>
</ListBoxItem>
<ListBoxItem>
<Expander Header="Expandable Stuff 2" IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
2
</Expander>
</ListBoxItem>
</ListBox>
Другое решение с кодом позади было бы таким:
<ListBox x:Name="ListBox" IsSynchronizedWithCurrentItem="True">
<ListBoxItem>
<Expander Header="Expandable Stuff 1" IsHitTestVisible="False" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
<StackPanel IsHitTestVisible="True">
<Label Content="1"/>
</StackPanel>
</Expander>
</ListBoxItem>
<ListBoxItem>
<Expander Header="Expandable Stuff 2" ButtonBase.Click="Expander_Click_1" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}">
2
</Expander>
</ListBoxItem>
</ListBox>
И код позади:
private void Expander_Click_1(object sender, RoutedEventArgs e)
{
if (sender is Expander)
{
Expander senderExp = (Expander)sender;
object obj = senderExp.Tag;
if (obj is ListBoxItem)
{
((ListBoxItem)obj).IsSelected = true;
}
}
}