UWP 未聚焦的 VisualState 覆盖了 ListViewItem 上的选定 VisualState
UWP unfocused VisualState overriding selected VisualState on ListViewItem
我有一个在其 ItemContainerStyle 上使用自定义样式的 ListView 属性。
问题是,当我使用键盘浏览列表中的项目时,如果我浏览到当前选定的项目,它会获得焦点样式(这很好),但是当我浏览时远离该项目,它开始使用未聚焦的样式而不是选定的样式。
例如,假设在 ListView 中选择了 5 项中的第 3 项。在列表获得焦点之前看起来像这样,这是正确的:
然后我使用键盘导航到列表,该列表将“聚焦”样式应用于所选项目,这很好...
但是当我按下向下箭头键向下导航时,突然间第三项看起来不再是“选中的”。看起来这只是一个普通的未选中项目:
发生这种情况是因为“未聚焦”状态覆盖了第三项的“选定”视觉状态,但我希望它是相反的。
注意:我在 ListView 上有 SingleSelectionFollowsFocus="False"。
如果我删除“未选择”状态,然后将焦点从第三个项目移开,我导航的任何项目看起来就像它当前处于聚焦状态...如果我能弄清楚为什么会这样,然后我可以安全地删除“未选择”状态,它会正常工作。
如何在取消聚焦后保留所选项目的“选定”视觉状态?
这是我的代码:
XAML:
<ListView x:Name="ThingieListView"
ItemsSource="{x:Bind viewModel.ThingieDataList}"
SingleSelectionFollowsFocus="False"
SelectionMode="Single"
IsItemClickEnabled="True"
XYFocusRight="{x:Bind LocationListView}"
Margin="8"
Width="256"
IsTabStop="True"
TabIndex="0"
LostFocus="ThingieListView_LostFocus"
GotFocus="ThingieListView_GotFocus"
ItemClick="ThingieListView_OnItemClick"
ItemContainerStyle="{StaticResource SelectThingieItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<ListViewItem Content="{Binding DisplayValue}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
自定义样式:
<Style x:Key="SelectThingieItemStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{StaticResource Res-FontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeText2}"/>
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter x:Name="Root"
CheckBrush="{ThemeResource ListViewItemCheckBrush}"
ContentMargin="15"
Height="63"
Margin="0 0 0 1"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
FocusVisualPrimaryThickness="0"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Control.IsTemplateFocusTarget="True"
PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"
RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}"
RevealBackground="{ThemeResource ListViewItemRevealBackground}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Gray_1}"/>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_4}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_4}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusedStates">
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderThickness" Value="0 0 20 0"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Gray_1}"/>
<Setter Target="Root.RevealBorderThickness" Value="0 1 0 1"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I retain the "selected" visual state of the selected item after unfocusing it?
正如你所说,“未聚焦”状态会覆盖“选中”状态,如果你想显示“选中”状态,你可以尝试在选中项丢失时手动触发“选中”视觉状态关注 VesselListView_LostFocus 事件。首先判断失去焦点的项目是否被选中,如果是,则可以触发“选中”状态。例如:
private void VesselListView_LostFocus(object sender, RoutedEventArgs e)
{
ListViewItem litem = e.OriginalSource as ListViewItem;
if (litem != null && litem.IsSelected == true)
{
VisualStateManager.GoToState(litem, "Selected", false);
}
}
我有一个在其 ItemContainerStyle 上使用自定义样式的 ListView 属性。
问题是,当我使用键盘浏览列表中的项目时,如果我浏览到当前选定的项目,它会获得焦点样式(这很好),但是当我浏览时远离该项目,它开始使用未聚焦的样式而不是选定的样式。
例如,假设在 ListView 中选择了 5 项中的第 3 项。在列表获得焦点之前看起来像这样,这是正确的:
然后我使用键盘导航到列表,该列表将“聚焦”样式应用于所选项目,这很好...
但是当我按下向下箭头键向下导航时,突然间第三项看起来不再是“选中的”。看起来这只是一个普通的未选中项目:
发生这种情况是因为“未聚焦”状态覆盖了第三项的“选定”视觉状态,但我希望它是相反的。
注意:我在 ListView 上有 SingleSelectionFollowsFocus="False"。
如果我删除“未选择”状态,然后将焦点从第三个项目移开,我导航的任何项目看起来就像它当前处于聚焦状态...如果我能弄清楚为什么会这样,然后我可以安全地删除“未选择”状态,它会正常工作。
如何在取消聚焦后保留所选项目的“选定”视觉状态?
这是我的代码:
XAML:
<ListView x:Name="ThingieListView"
ItemsSource="{x:Bind viewModel.ThingieDataList}"
SingleSelectionFollowsFocus="False"
SelectionMode="Single"
IsItemClickEnabled="True"
XYFocusRight="{x:Bind LocationListView}"
Margin="8"
Width="256"
IsTabStop="True"
TabIndex="0"
LostFocus="ThingieListView_LostFocus"
GotFocus="ThingieListView_GotFocus"
ItemClick="ThingieListView_OnItemClick"
ItemContainerStyle="{StaticResource SelectThingieItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<ListViewItem Content="{Binding DisplayValue}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
自定义样式:
<Style x:Key="SelectThingieItemStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{StaticResource Res-FontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeText2}"/>
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter x:Name="Root"
CheckBrush="{ThemeResource ListViewItemCheckBrush}"
ContentMargin="15"
Height="63"
Margin="0 0 0 1"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
FocusVisualPrimaryThickness="0"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Control.IsTemplateFocusTarget="True"
PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"
RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}"
RevealBackground="{ThemeResource ListViewItemRevealBackground}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Gray_1}"/>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_4}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_4}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="3"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusedStates">
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Target="Root.FontWeight" Value="Bold"/>
<Setter Target="Root.Foreground" Value="{StaticResource Res-Black}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBorderThickness" Value="0 0 20 0"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Orange}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused">
<VisualState.Setters>
<Setter Target="Root.Foreground" Value="{StaticResource Res-White}"/>
<Setter Target="Root.RevealBackground" Value="{StaticResource Res-Gray_2}"/>
<Setter Target="Root.RevealBorderBrush" Value="{StaticResource Res-Gray_1}"/>
<Setter Target="Root.RevealBorderThickness" Value="0 1 0 1"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I retain the "selected" visual state of the selected item after unfocusing it?
正如你所说,“未聚焦”状态会覆盖“选中”状态,如果你想显示“选中”状态,你可以尝试在选中项丢失时手动触发“选中”视觉状态关注 VesselListView_LostFocus 事件。首先判断失去焦点的项目是否被选中,如果是,则可以触发“选中”状态。例如:
private void VesselListView_LostFocus(object sender, RoutedEventArgs e)
{
ListViewItem litem = e.OriginalSource as ListViewItem;
if (litem != null && litem.IsSelected == true)
{
VisualStateManager.GoToState(litem, "Selected", false);
}
}