2015-06-08 5 views
7

У меня проблема с ListBoxItem s. Я пытаюсь сделать все элементы управления в ListBoxItem, также выберите его, так что нажав на TextBox, Label и т. Д., Выберете ListBoxItem. Довольно просто.WPF ListBoxItem ControlTemplate разбивает некоторые MouseDown/Selection

Я также меняю ListBoxItem Шаблон, чтобы изменить визуализацию выбора, выделив фон, чтобы просто нарисовать границу. Также довольно просто.

Сочетание этих двух, однако, кажется, вызывает некоторые действительно раздражающие проблемы с MouseDown и PreviewMouseDown, в частности, в моем случае относительно Label с в Grid, где один создает «пустоты» занято Grid пространства.

Использование Snoop, я могу видеть PreviewMouseDown событие остановки в ScrollViewer внутри ListBox, и не пройдя весь путь к ListBoxItem.

click no worky

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-за:

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; 
     } 
    } 
} 

Однако, если я удалю Template сеттер, все хорошо. Есть ли какая-то магия в шаблоне, который мне не хватает? Я попробовал переименовать границу в «Bd», так как это было названо границей шаблона по умолчанию, но не повезло. Есть идеи?

+0

Вы пытаетесь получить границу, нарисованную при нажатии в пробеле справа от второго элемента списка? –

+0

@aaron, я пытаюсь выбрать 'ListBoxItem', щелкнув _anywhere_ внутри него и показывая выделение через границу (например, верхний выбранный элемент на снимке экрана). Код работает повсюду, кроме пустоты справа от «ShortLabel». –

+0

Не знал, что вы можете использовать Snoop для просмотра событий! – Contango

ответ

5

Если вы измените горизонтальное выравнивание меток от «Влево» до «Растянуть», это устранит проблему и сохранит визуальное форматирование одинаково.

События Mousedown работают только в тех областях, где существуют элементы. Имея метки в горизонтальном выравнивании «слева», вы создаете «пустоту», о которой вы упомянули, где на этом уровне не существует элемента. Чтобы визуально увидеть разницу, попробуйте временно установить свойство фона элементов ярлыка, которое создает проблемы, и вы увидите, что элемент не распространяется полностью на текстовое поле.

+0

Блестящий! Это устраняет проблему, которая у меня была в моем проекте. – Contango

+0

Так просто. Спасибо! Я полагал, что «ListBoxItem» получит событие «MouseDown» в такой ситуации, где есть пустота. Еще раз спасибо! –

+0

Любая идея, почему 'ListBoxItem' не получает событие? Я чувствую, что это хорошее решение, но это не объясняет, почему это событие, кажется, умирает в 'ScrollViewer'. –