[英]WPF ListBox selection issues, providing feedback to user
我正在尝试为具有一个画布但有多个“页面”的应用程序创建一个显示页面内容缩略图视图的列表框。 是的,那可能不是最好的起点,但由于历史原因,这就是我所拥有的。 我已经实现了将ListBox与数据绑定到具有ObservableCollection的PageData的单例“ WorkBook”(出现在页面上的所有内容,包括其背景)。 我真正想要的是能够在选择ListBoxItem时更改其Border颜色,并在其内容为宿主集合的类中当前选定的项目时保留该Border color。
我的问题是:-1 /我无法在程序启动时让ListBox选择第一项。
2 /当列表框失去焦点时,SelectedIndex始终为-1(因此没有选择)
3 /添加到列表框将导致没有选择(SelectedIndex == -1)
4 /使用触发器,我可以设置selectedItem的边框,但是当ListBox失去焦点时,边框会丢失。 由于ListBoxItem显示的图像是不透明的,因此当焦点模糊时,保留选择颜色的“标准”方法不起作用-即
<Style x:Key="PsThumb">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White"></SolidColorBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="White"></SolidColorBrush>
</Style.Resources>
</Style>
我的ListBox代码如下:-
<ListBox x:Name="PageSorter" Style="{StaticResource PsThumb}" Width="148" BorderThickness="4" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
VerticalAlignment="Stretch" ItemsSource="{Binding Pages,Source={StaticResource WorkBook}}" SelectedItem="{Binding Path=CurrentPageData, Mode=TwoWay}"
AllowDrop="True" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border x:Name="border" BorderBrush="DarkGray" BorderThickness="4" Margin="2,4,2,4" CornerRadius="5">
<Border.Effect>
<DropShadowEffect ShadowDepth="6"/>
</Border.Effect>
<Image Source="{Binding Thumbnail}" Width="130" Height="95" Stretch="Fill"/>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Red"></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
实现您要求的最简单方法是将DataTrigger
绑定到ListBox
项内的属性。 在下面的示例中,我在Contact
类上添加了Selected
属性:
public class Contact : INPCBase
{
public string Name { get; set; }
private bool _Selected;
public bool Selected
{
get { return _Selected; }
set
{
_Selected = value;
NotifyPropertyChanged("Selected");
}
}
}
然后,将ListBox
绑定到List<Contact>
。 当用户Selected
CheckBox
,我们将更改Selected
属性,然后触发Style
:
<Window x:Class="WpfApp.ListboxKeepSelectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ListboxKeepSelectionWindow" Height="277" Width="343"
xmlns:me="clr-namespace:WpfApp">
<Window.Resources>
<me:ContactList x:Key="sample"/>
<Style TargetType="ListBoxItem" x:Key="SelectedListBoxItemStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Selected}" Value="True">
<Setter Property="BorderBrush" Value="Orange"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListBox Name="lbxContacts"
ItemsSource="{StaticResource ResourceKey=sample}"
SelectionMode="Extended"
ItemContainerStyle="{StaticResource ResourceKey=SelectedListBoxItemStyle}"
SelectionChanged="lbxContacts_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding Path=Selected}">
<TextBlock Text="{Binding Path=Name}"/>
</CheckBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
为了允许用户选择项目而不使用复选框,我在ListBox
上添加了这个小事件。 由于Contact
类实现了INotifyPropertyChanged
接口,因此CheckBox
的值已更新,因此用户知道选择有效:
private void lbxContacts_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (Contact c in e.AddedItems)
{
c.Selected = !c.Selected;
}
}
当您想要获得选定项目的列表时,只需在ItemsSource
上使用LINQ查询即可获得其中Selected == true
项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.