Mam problem z ListBoxItem
s. Próbuję ustawić wszystkie elementy sterujące w ListBoxItem
również je zaznacz, więc kliknięcie na TextBox
, Label
itp. Wybierze ListBoxItem
. Do tej pory dość proste.WPF ListBoxItem ControlTemplate łamie niektóre MouseDown/Selection
Zmieniam również szablon ListBoxItem
, aby zmienić wizualizację zaznaczenia z podświetlenia tła po prostu rysowanie obramowania. Również całkiem proste.
Połączenie tych dwóch, jednak wydaje się powodować pewne naprawdę irytujące problemy z MouseDown
i PreviewMouseDown
, szczególnie w moim przypadku dotyczące Label
s w Grid
, w których jeden tworzy „void” zajęte przez Grid
przestrzeni.
Korzystanie snoop, widzę zdarzenie PreviewMouseDown
zatrzymując się na ScrollViewer
wewnątrz ListBox
, a nie dzieje się aż do ListBoxItem
.
XAML:
<Window x:Class="ListBoxClickThroughTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<Grid>
<ListBox ItemsSource="{Binding Items}"
SelectionMode="Single">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Name="VerySuperLongLabel"
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Left"
Content="VerySuperLongLabel"
Padding="0" />
<TextBox Name="Textbox1"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Right"
Text="Textbox1 Text" />
<Label Name="ShortLabel"
Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Left"
Content="ShortLabel"
Padding="0" />
<TextBox Name="Textbox2"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Right"
Text="Textbox2 Text" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="PreviewMouseDown"
Handler="ListBoxItem_PreviewMouseDown" />
<EventSetter Event="MouseDown"
Handler="ListBoxItem_PreviewMouseDown" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd"
BorderThickness="1">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="BorderBrush" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</Window>
Code-tył:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace ListBoxClickThroughTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
Items = new List<string>() { "1", "2" };
InitializeComponent();
DataContext = this;
}
public List<string> Items { get; set; }
private void ListBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var listBoxItem = (ListBoxItem)sender;
listBoxItem.IsSelected = true;
}
}
}
Jednak jeśli usunąć Template
setter, wszystko jest dobrze. Czy w szablonie brakuje jakiejś magii? Próbowałem zmienić nazwę ramki na "Bd", ponieważ była to nazwa domyślnej granicy szablonu, ale bez powodzenia. Jakieś pomysły?
Czy próbujesz uzyskać obramowanie rysowane po kliknięciu w białą spację na prawo od drugiego elementu listy? –
@aaron, Próbuję wybrać 'ListBoxItem' klikając w nim _anywhere_ i pokazując zaznaczenie za pomocą ramki (jak górny wybrany element na zrzucie ekranu). Kod działa wszędzie z wyjątkiem pustki po prawej stronie "ShortLabel". –
Nie wiedziałeś, że możesz używać Snoopa do oglądania wydarzeń! – Contango