我希望在Windows资源管理器的IconView中有键盘导航,即如果我们移动到屏幕选择宽度的末尾,则应移动到下一行....
<ListView Name="lv"
Grid.Row="1"
Width="Auto"
Height="Auto"
IsTextSearchEnabled="True"
ItemsSource="{Binding Path=Persons}"
KeyboardNavigation.DirectionalNavigation="Continue"
SelectedItem="{Binding Path=SelectedPerson}"
SelectionMode="Single"
View="{StaticResource ResourceKey=plainView}">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
</ListView>
答案 0 :(得分:0)
在Generic.xaml中定义ListView默认样式如下:
<Style TargetType="{x:Type ListView}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Visible" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Trebuchet MS" />
<Setter Property="FontSize" Value="12" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Grid>
<Border x:Name="Border"
Background="{DynamicResource ControlBackgroundBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="1">
<ScrollViewer Margin="{TemplateBinding Padding}" IsTabStop="False">
<ItemsPresenter/>
</ScrollViewer>
</Border>
<Border x:Name="DisabledVisualElement"
Background="#A5FFFFFF"
BorderBrush="#66FFFFFF"
BorderThickness="1"
IsHitTestVisible="false"
Opacity="0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="DisabledVisualElement" Property="Opacity" Value="1" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value >
<ItemsPanelTemplate>
<WrapPanel Height="{Binding ActualHeight,
RelativeSource={RelativeSource AncestorType=Border}}"
MinWidth="{Binding (ListView.View).MinWidth,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListView}}}"
Focusable="False"
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Contained"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListView}}}"
Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
一点解释:您的WrapPanel
占据了ScrollViewer
的所有可用尺寸,这几乎是无限的。如果你想让你的物品在Vertical WrapPanel中可以滚动,你应该以水平宽度来限制你的身高。
答案 1 :(得分:0)
我发现实现这一目标的唯一方法是手动解释中的按键 PreviewKeyDown事件并设置selectedindex。 您必须将handle设置为true,否则listview也会解释键,这会导致错误的键导航。
以下是两个键的示例:
private void listView_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (listView.SelectedIndex >= 0)
{
if (e.Key == Key.Right)
{
listView.SelectedIndex++;
}
if (e.Key == Key.Left)
{
listView.SelectedIndex--;
}
e.Handled = true;
}
}
编辑:使用MVVMLight Toolkit的100%纯MVVM方式
XAML:
xmlns:mvvmLight="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
>
<Grid>
<ListView SelectedIndex="{Binding SelectedIndex}" ItemsSource="{Binding Items}" x:Name="listView">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<mvvmLight:EventToCommand PassEventArgsToCommand="True" Command="{Binding PreviewKeyDownCommand}"></mvvmLight:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
视图模型:
public ICommand PreviewKeyDownCommand
{
get
{
return new RelayCommand<Object>(x => this.PreviewKeyDown(x as KeyEventArgs));
}
}
private void PreviewKeyDown(KeyEventArgs e)
{
if (SelectedIndex >= 0)
{
if (e.Key == Key.Right)
{
SelectedIndex++;
}
if (e.Key == Key.Left)
{
SelectedIndex--;
}
}
e.Handled = true;
}
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
NotifyPropertyChanged("SelectedIndex");
}
}