2009-11-06 5 views
1

J'ai une fenêtre avec deux ListBox es tous deux liés à un XMLDataProvider. La propriété SelectedItem de Listbox1 est liée à la propriété SelectedItem de ListBox2. Jusqu'ici tout va bien.comportement étrange de Listboxes dans WPF

ListBox2 contient un StyleTrigger qui définit IsSelected à true lorsque la souris survole un élément. L'élément correspondant dans ListBox1 est également sélectionné en raison de la liaison bidirectionnelle. Le problème se pose lorsque je sélectionne un élément dans Listbox1 en cliquant dessus

Par exemple, lorsque je sélectionne « livre 1 » dans ListBox1 puis déplacez la souris sur tous les éléments en ListBox2 l'élément « Livre 1 » ne sera plus sélectionné lorsque le style déclenche les incendies. Dès que je sélectionne un article dans Listbox1 je ne peux plus sélectionner l'article correspondant dans Listbox2 en déplaçant la souris dessus. Cependant, la sélection par clic de souris fonctionne toujours. Est-ce que quelqu'un peut expliquer le comportement et/ou fournir une solution?

<Window x:Class="Test.sample" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     SizeToContent="WidthAndHeight"> 

    <Window.Resources> 
     <Style TargetType="ListBox"> 
      <Style.Setters> 
       <Setter Property="Width" Value="150"/> 
       <Setter Property="Margin" Value="4"/> 
      </Style.Setters> 
     </Style> 

     <!-- define the XML data source as a resource --> 
     <XmlDataProvider x:Key="TestData" XPath="/Books"> 
      <x:XData> 
       <Books xmlns=""> 
        <Book> 
         <Title>Book 1</Title> 
         <Author>Mister 1</Author> 
        </Book> 
        <Book> 
         <Title>Book 2</Title> 
         <Author>Mister 2</Author> 
        </Book> 
        <Book> 
         <Title>Book 3</Title> 
         <Author>Mister 3</Author> 
        </Book> 
        <Book> 
         <Title>Book 4</Title> 
         <Author>Mister 4</Author> 
        </Book> 
        <Book> 
         <Title>Book 5</Title> 
         <Author>Mister 5</Author> 
        </Book> 
        <Book> 
         <Title>Book 6</Title> 
         <Author>Mister 6</Author> 
        </Book> 
       </Books> 
      </x:XData> 
     </XmlDataProvider> 

    </Window.Resources> 
    <Grid> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel> 
       <Label HorizontalContentAlignment="Center">Listbox 1</Label> 
       <ListBox x:Name="box1" ItemsSource="{Binding Source={StaticResource TestData}, XPath=Book}" 
        SelectedItem="{Binding ElementName=box2, Path=SelectedItem, Mode=TwoWay}"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Label Content="{Binding XPath=Title}"/> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 
      </StackPanel> 
      <StackPanel> 
       <Label HorizontalContentAlignment="Center">Listbox 2</Label> 
       <ListBox x:Name="box2" ItemsSource="{Binding Source={StaticResource TestData}, XPath=Book}"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Label Content="{Binding XPath=Title}"/> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
        <ListBox.ItemContainerStyle> 
         <Style TargetType="ListBoxItem"> 
          <Style.Triggers> 
           <Trigger Property="IsMouseOver" Value="True"> 
            <Setter Property="Padding" Value="12"/> 
            <Setter Property="IsSelected" Value="True"/> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </ListBox.ItemContainerStyle> 
       </ListBox> 
      </StackPanel> 
     </StackPanel> 
    </Grid> 
</Window> 
+0

+1 pour fournir un exemple complet et runnable explication claire, désolé ne peut pas vous aider à bien .. :) – Oskar

Répondre

3

Le problème est dû à la liaison bidirectionnelle. Lorsque vous sélectionnez un élément dans ListBox 1, il définit la propriété SelectedItem sur ListBox 2. Cela «remplace» le Binding défini sur ListBox2.SelectedItem. Si vous le souhaitez, vous pouvez vérifier dans Snoop. Pour ce faire, vous devez utiliser une vue de collection et la propriété IsSynchronizedWithCurrentItem. Les deux ListBox doivent se lier à la même vue de collection et être synchronisés avec l'élément en cours. Par conséquent, la sélection d'un élément dans un ListBox forcera l'autre ListBox à se synchroniser avec l'élément sélectionné.

Voici le XAML minimum dont vous avez besoin pour y arriver:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <Style TargetType="ListBox"> 
      <Style.Setters> 
       <Setter Property="Width" Value="150"/> 
       <Setter Property="Margin" Value="4"/> 
      </Style.Setters> 
     </Style> 

     <!-- define the XML data source as a resource --> 
     <XmlDataProvider x:Key="TestData" XPath="/Books"> 
      <x:XData> 
       <Books xmlns=""> 
        <Book> 
         <Title>Book 1</Title> 
         <Author>Mister 1</Author> 
        </Book> 
        <Book> 
         <Title>Book 2</Title> 
         <Author>Mister 2</Author> 
        </Book> 
        <Book> 
         <Title>Book 3</Title> 
         <Author>Mister 3</Author> 
        </Book> 
        <Book> 
         <Title>Book 4</Title> 
         <Author>Mister 4</Author> 
        </Book> 
        <Book> 
         <Title>Book 5</Title> 
         <Author>Mister 5</Author> 
        </Book> 
        <Book> 
         <Title>Book 6</Title> 
         <Author>Mister 6</Author> 
        </Book> 
       </Books> 
      </x:XData> 
     </XmlDataProvider> 

     <CollectionViewSource x:Key="cvs" Source="{Binding Source={StaticResource TestData}, XPath=Book}"/> 
    </Window.Resources> 
    <Grid> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel> 
       <Label HorizontalContentAlignment="Center">Listbox 1</Label> 
       <ListBox x:Name="box1" ItemsSource="Source={StaticResource cvs}}" IsSynchronizedWithCurrentItem="True"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Label Content="{Binding XPath=Title}"/> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 
      </StackPanel> 
      <StackPanel> 
       <Label HorizontalContentAlignment="Center">Listbox 2</Label> 
       <ListBox x:Name="box2" ItemsSource="{Binding Source={StaticResource cvs}}" IsSynchronizedWithCurrentItem="True"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Label Content="{Binding XPath=Title}"/> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 
      </StackPanel> 
     </StackPanel> 
    </Grid> 
</Window> 
+0

Merci pour votre suggestion. Malheureusement, le problème persiste. Dès que je sélectionne un élément dans Listbox1, il ne sera plus sélectionné dans ListBox2 lorsque le déclencheur IsMouseOver se déclenchera. –

+0

Vous avez copié le code ci-dessus et cela ne fonctionne pas? Fonctionne bien pour moi. –

+0

Votre code fonctionne mais le déclencheur de style de Listbox2 qui provoque le problème est manquant dans votre exemple. –