WPF中列表框的奇怪行为
我有一个窗口,其中有两个WPF中列表框的奇怪行为,wpf,xaml,select,binding,listbox,Wpf,Xaml,Select,Binding,Listbox,我有一个窗口,其中有两个ListBoxes都绑定到XMLDataProvider。Listbox1的SelectedItem属性双向绑定到ListBox2的SelectedItem属性。到目前为止还不错 ListBox2包含一个样式触发器,当鼠标悬停在项目上时,该触发器将IsSelected设置为true。由于双向绑定,因此也选择了列表框1中的相应项。当我通过单击列表框1中的某个项目来选择该项目时,就会出现问题 例如,当我在ListBox1中选择“Book 1”,然后将鼠标移到ListBox2中
ListBox
es都绑定到XMLDataProvider
。Listbox1
的SelectedItem
属性双向绑定到ListBox2
的SelectedItem
属性。到目前为止还不错
ListBox2
包含一个样式
触发器
,当鼠标悬停在项目上时,该触发器将IsSelected
设置为true。由于双向绑定,因此也选择了列表框1
中的相应项。当我通过单击列表框1
中的某个项目来选择该项目时,就会出现问题
例如,当我在ListBox1
中选择“Book 1”,然后将鼠标移到ListBox2
中的所有项目上时,当触发样式触发器时,将不再选择项目“Book 1”。一旦我在Listbox1
中选择了一个项目,我就不能再通过在Listbox2
中移动鼠标来选择相应的项目。但是,通过鼠标单击进行选择仍然有效
有人能解释这种行为和/或提供解决方案吗
<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>
第一册
先生1
第二册
先生2
第三册
先生3
第四册
先生4
第五册
先生5
第六册
先生6
列表框1
列表框2
该问题是由双向绑定引起的。当您在ListBox
1中选择一个项目时,它会在ListBox
2上设置SelectedItem
属性。这将“覆盖”列表框2上的绑定设置。选择editem
。如果需要,可以在中验证
至于如何实现您的目标,您应该使用集合视图和属性。两个ListBox
es都应绑定到同一集合视图,并与当前项同步。因此,在一个列表框
中选择一个项目将强制另一个列表框
与所选项目同步
以下是实现此目标所需的最小XAML:
<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>
第一册
先生1
第二册
先生2
第三册
先生3
第四册
先生4
第五册
先生5
第六册
先生6
列表框1
列表框2
+1为了提供一个完整的可运行示例和清晰的解释,抱歉,我无法帮助您……)谢谢你的建议。不幸的是,问题依然存在。一旦我在Listbox1中选择了一个项目,当IsMouseOver触发器触发时,它将不再在ListBox2中被选中。您复制了上面的代码,但它不起作用?对我来说还可以。您的代码可以工作,但是在您的示例中缺少导致问题的Listbox2的样式触发器。样式触发器设置为IsSelected,因此正如我的回答中所述覆盖绑定。我已经研究了snoop的问题,我想说是另一种方式:绑定覆盖样式触发器。我仍然可以通过单击两个列表框中的项目来选择它们,并且在另一个列表框中选择相同的项目。触发器触发,但在ListBox1中选择相应项后不再设置IsSelected。有什么办法可以让触发器工作吗?