.NET MAUI:Windows平台VisualStateManager选中项失焦问题求助
解决.NET MAUI CollectionView在Windows平台选中项失焦后样式重置的问题
你在.NET MAUI项目中实现了CollectionView单项选择功能,通过VisualStateManager设置选中项背景为黄色、关联Label文字为红色,该功能在Android平台正常,但Windows平台下鼠标光标移开后,选中项会失去焦点,样式随之恢复。这是因为Windows平台上CollectionView的默认ItemContainer会将选中状态与焦点状态绑定,失焦后VisualState会切换回Normal,导致样式重置。
解决方案:使用DataTrigger绑定选中状态替代VisualState
直接绑定CollectionViewItem的IsSelected属性,通过DataTrigger设置样式,这样即使失去焦点,只要项处于选中状态,样式就会保持。
修改后的完整XAML代码
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SelectionTest.MainPage"> <ContentPage.Resources> <!-- 复用的选中项StackLayout样式 --> <Style TargetType="StackLayout" x:Key="SelectedItemStackStyle"> <Style.Triggers> <DataTrigger Binding="{Binding Source={RelativeSource AncestorType={x:Type CollectionViewItem}}, Path=IsSelected}" Value="True"> <Setter Property="BackgroundColor" Value="Yellow" /> </DataTrigger> </Style.Triggers> </Style> <!-- 复用的选中项Label样式 --> <Style TargetType="Label" x:Key="SelectedItemLabelStyle"> <Style.Triggers> <DataTrigger Binding="{Binding Source={RelativeSource AncestorType={x:Type CollectionViewItem}}, Path=IsSelected}" Value="True"> <Setter Property="TextColor" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </ContentPage.Resources> <StackLayout> <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0"> <Label Text="Visual State Manager Sample" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/> </Frame> <Entry Text="Please subscribe to my channel!"/> <CollectionView SelectionMode="Single"> <CollectionView.ItemsSource> <x:Array Type="{x:Type x:String}"> <x:String>111111111</x:String> <x:String>222222222</x:String> <x:String>333333333</x:String> </x:Array> </CollectionView.ItemsSource> <CollectionView.ItemTemplate> <DataTemplate> <StackLayout Style="{StaticResource SelectedItemStackStyle}"> <Label x:Name="valueLabel" Text="{Binding .}" HorizontalTextAlignment="Center" Style="{StaticResource SelectedItemLabelStyle}" /> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </ContentPage>
关键说明
RelativeSource AncestorType={x:Type CollectionViewItem}用于绑定到当前项的容器控件,获取其IsSelected属性值。- DataTrigger会监听
IsSelected的变化,当值为True时自动应用指定样式,该状态不会因焦点丢失而改变,直到用户选择其他项。 - 将样式定义在
ContentPage.Resources中可实现复用,避免重复代码。
替代方案:自定义ItemContainerStyle的VisualState
如果你更倾向于使用VisualStateManager,可以直接为CollectionView的ItemContainer添加SelectedUnfocused状态的样式,确保失焦后选中样式依然保留:
<CollectionView SelectionMode="Single"> <!-- 其他代码不变 --> <CollectionView.ItemContainerStyle> <Style TargetType="CollectionViewItem"> <Setter Property="VisualStateManager.VisualStateGroups"> <VisualStateGroupList> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="Yellow" /> </VisualState.Setters> </VisualState> <VisualState x:Name="SelectedUnfocused"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="Yellow" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </Setter> </Style> </CollectionView.ItemContainerStyle> </CollectionView>
此方案中,Label的文字颜色仍需通过DataTrigger绑定IsSelected属性来设置,因为ItemContainer的VisualState无法直接控制内部Label的样式。
内容的提问来源于stack exchange,提问作者phmeek
相关产品推荐
相关产品推荐

