我们要设定SelectedItem的ListBox程序,并希望该项目则有焦点,使方向键的作用相对于选定的项目.看起来很简单.
然而问题是,如果在以编程方式ListBox设置时已经具有键盘焦点SelectedItem,而它正确地更新了该IsSelected属性ListBoxItem,则它不会将键盘焦点设置到它,因此,箭头键相对于之前关注的项目移动列表而不是人们所期望的新选择的项目.
这对用户来说非常混乱,因为它使选择似乎在使用键盘时跳转,因为它快速回到编程选择发生之前的位置.
注意:正如我所说,只有SelectedItem在以编程方式在ListBox已经具有键盘焦点的属性上设置属性时才会发生这种情况.如果它没有(或者如果它没有,你会离开,然后再回来),当键盘焦点返回时ListBox,正确的项目现在将按预期进行键盘焦点.
这是一些显示此问题的示例代码.要进行演示,请运行代码,使用鼠标在列表中选择"Seven"(从而将焦点放在其上ListBox),然后单击"Test"按钮.最后,点击键盘上的"Alt"键以显示焦点rect.您将看到它仍然实际上在'Seven'上,如果您使用向上和向下箭头,它们是相对于该行,而不是用户期望的'四'.
请注意,我已将按钮Focusable设置为false在按下按钮时不抢夺焦点列表框.如果我没有这个,ListBox当你点击按钮时会失去焦点,因此,当焦点返回到ListBox时,它将在正确的项目上.
XAML文件:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="525" Height="350" WindowStartupLocation="CenterScreen"
Title="MainWindow" x:Name="Root">
<DockPanel>
<Button Content="Test"
DockPanel.Dock="Bottom"
HorizontalAlignment="Left"
Focusable="False"
Click="Button_Click" />
<ListBox x:Name="MainListBox" />
</DockPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
代码隐藏:
using System.Collections.ObjectModel;
using System.Windows;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainListBox.ItemsSource = new string[]{ …Run Code Online (Sandbox Code Playgroud) 我有一个包含图像和按钮的列表框.默认情况下,该按钮是隐藏的.每当我将鼠标悬停在列表框中的某个项目上时,我想让按钮可见.我正在使用的XAML如下.谢谢
<Window.Resources>
<Style TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="6">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=FullPath}" Height="150" Width="150"/>
<Button x:Name="sideButton" Width="20" Visibility="Hidden"/>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud) 我有一个数据绑定和itemtemplated ListBox:
<ListBox x:Name="lbLista"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Deleteable, Mode=TwoWay}" />
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
它显示很好,它们来自ObservableCollection.
该问题是滚动条出现,但无法使用-它不会有一个把手抢.我已经尝试在ListBox上设置一些ScrollView附加属性,但它们不会影响这种情况.
我希望在ListBox中的某个项被鼠标单击时得到通知,无论它是否已被选中.
我搜索并发现了这个:(http://kevin-berridge.blogspot.com/2008/06/wpf-listboxitem-double-click.html查看评论)
private void AddDoubleClickEventStyle(ListBox listBox, MouseButtonEventHandler mouseButtonEventHandler)
{
if (listBox.ItemContainerStyle == null)
listBox.ItemContainerStyle = new Style(typeof(ListBoxItem));
listBox.ItemContainerStyle.Setters.Add(new EventSetter()
{
Event = MouseDoubleClickEvent,
Handler = mouseButtonEventHandler
});
}
//Usage:
AddDoubleClickEventStyle(listView1, new MouseButtonEventHandler(listView1_MouseDoubleClick));
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它是为了它DoubleClick.虽然我不能让它工作一次.我试过MouseLeftButtonDownEvent- 因为似乎没有MouseClick事件,但它没有被调用.
一个更普遍的侧面问题:我怎样才能看到哪些事件确实存在,哪些处理程序与它们对应以及何时实际执行某些操作?例如,什么告诉我,MouseDoubleClickEvent我需要一个MouseButtonEventHandler?也许对于MouseLeftButtonDownEvent我需要一些其他处理程序,这就是为什么它不起作用?
我也尝试了子类化ListBoxItem和覆盖OnMouseLeftButtonDown- 但它也没有被调用.
渣
在XAML中是否有办法确定ListBox是否有数据?
如果没有数据,我想将其IsVisibile属性设置为false.
我无法找到如何不允许我的ListBox突出显示所选项目.我知道我没有添加触发器来突出显示该项目.
<ListBox Name="CartItems" ItemsSource="{Binding}"
ItemTemplate="{StaticResource TicketTemplate}"
Grid.Row="3" Grid.ColumnSpan="9" Background="Transparent"
BorderBrush="Transparent">
</ListBox>
Run Code Online (Sandbox Code Playgroud) 我有一些奇怪的行为,我似乎无法解决.当我遍历ListBox.ItemsSource属性中的项目时,我似乎无法获取容器?我期待看到一个ListBoxItem返回,但我只得到null.
有任何想法吗?
这是我正在使用的一些代码:
this.lstResults.ItemsSource.ForEach(t =>
{
ListBoxItem lbi = this.lstResults.ItemContainerGenerator.ContainerFromItem(t) as ListBoxItem;
if (lbi != null)
{
this.AddToolTip(lbi);
}
});
Run Code Online (Sandbox Code Playgroud)
ItemsSource当前设置为Dictionary并且包含许多KVP.
我正在制作一个可通过自定义"下一步"和"后退"按钮和命令(即不使用a NavigationWindow)导航的WPF应用程序.在一个屏幕上,我有一个ListBox必须支持多个选择(使用Extended模式).我有一个该屏幕的视图模型,并将所选项目存储为属性,因为它们需要维护.
但是,我知道SelectedItemsa 的属性ListBox是只读的.我一直在尝试使用此解决方案解决此问题,但我无法将其应用到我的实现中.我发现无法区分何时取消选择一个或多个元素以及何时在屏幕之间导航(NotifyCollectionChangedAction.Remove在两种情况下都会引发,因为从技术上讲,所有选定的项目在远离屏幕时都会被取消选择).我的导航命令位于一个单独的视图模型中,该模型管理每个屏幕的视图模型,因此我不能将任何与视图模型相关的实现与其中相关联ListBox.
我发现了其他一些不太优雅的解决方案,但这些解决方案似乎都没有强制实现视图模型和视图之间的双向绑定.
任何帮助将不胜感激.我可以提供一些我的源代码,如果它有助于理解我的问题.
我有一个非常简单的WPF ListBox,SelectionMode设置为Multiple.
<ListBox SelectionMode="Multiple" />
Run Code Online (Sandbox Code Playgroud)
当ListBox失去焦点时,由于选择颜色从蓝色变为浅灰色,因此很难确定选择了什么.更改此行为以使其保持蓝色的最简单方法是什么?
我知道这可能与ListItem的风格有关,但我无法找到它.
干杯.
我创建了两个RadioButton(重量和高度).我会在两个类别之间切换.但是它们共享相同的ListBox控制器(listBox1和listBox2).
有没有什么好方法可以更简单地清除所有ListBox项?我找不到ListBox的removeAll().我不喜欢我在这里发布的复杂的多行样式.
private void Weight_Click(object sender, RoutedEventArgs e)
{
// switch between the radioButton "Weith" and "Height"
// Clear all the items first
listBox1.Items.Remove("foot");
listBox1.Items.Remove("inch");
listBox1.Items.Remove("meter");
listBox2.Items.Remove("foot");
listBox2.Items.Remove("inch");
listBox2.Items.Remove("meter");
// Add source units items for listBox1
listBox1.Items.Add("kilogram");
listBox1.Items.Add("pound");
// Add target units items for listBox2
listBox2.Items.Add("kilogram");
listBox2.Items.Add("pound");
}
private void Height_Click(object sender, RoutedEventArgs e)
{
// switch between the radioButton "Weith" and "Height"
// Clear all the items first
listBox1.Items.Remove("kilogram");
listBox1.Items.Remove("pound");
listBox2.Items.Remove("kilogram");
listBox2.Items.Remove("pound");
// Add source units items for listBox1 …Run Code Online (Sandbox Code Playgroud) listbox ×10
wpf ×10
xaml ×3
c# ×2
.net ×1
click ×1
containers ×1
events ×1
itemssource ×1
listboxitem ×1
mvvm ×1
scroll ×1
selecteditem ×1