You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:31:42