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

UWP WinUI2:如何为禁用的GridViewItem显示ToolTip

UWP中为禁用的GridViewItem显示ToolTip的解决方案

由于UWP中禁用的控件无法接收指针事件,也没有WPF的ToolTipService.ShowOnDisabled属性,我们可以通过在DataTemplate中添加透明覆盖层的方式绕过限制,让覆盖层捕获指针事件并显示ToolTip。

方法一:绑定数据源标记(推荐)

1. 修改数据源对象

在CustomDataObject中添加两个属性,标记是否禁用和对应的提示文本:

public class CustomDataObject : INotifyPropertyChanged
{
    // 原有属性:Title、ImageLocation、Views、Likes
    
    private bool _isDisabled;
    public bool IsDisabled
    {
        get => _isDisabled;
        set { _isDisabled = value; OnPropertyChanged(); }
    }

    private string _disabledToolTipText;
    public string DisabledToolTipText
    {
        get => _disabledToolTipText;
        set { _disabledToolTipText = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 更新DataTemplate

在最外层Grid内添加一个覆盖整个区域的透明Border,仅当项禁用时接收指针事件并显示ToolTip:

<DataTemplate x:Key="ImageTextTemplate" x:DataType="local1:CustomDataObject">
    <Grid AutomationProperties.Name="{x:Bind Title}" Width="280">
        <!-- 透明覆盖层,用于捕获指针事件 -->
        <Border 
            Background="Transparent"
            IsHitTestVisible="{x:Bind IsDisabled, Mode=OneWay}"
            ToolTipService.ToolTip="{x:Bind DisabledToolTipText}">
        </Border>

        <!-- 原有布局内容 -->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Image Source="{x:Bind ImageLocation}" Height="100" Stretch="Fill" VerticalAlignment="Top"/>
        <StackPanel Grid.Column="1" Margin="8,0,0,8">
            <TextBlock Text="{x:Bind Title}" Style="{ThemeResource SubtitleTextBlockStyle}" Margin="0,0,0,8"/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{x:Bind Views}" Style="{ThemeResource CaptionTextBlockStyle}"/>
                <TextBlock Text=" Views " Style="{ThemeResource CaptionTextBlockStyle}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{x:Bind Likes}" Style="{ThemeResource CaptionTextBlockStyle}" />
                <TextBlock Text=" Likes" Style="{ThemeResource CaptionTextBlockStyle}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</DataTemplate>

3. 更新ContainerContentChanging处理器

在禁用GridViewItem的同时,设置数据源的禁用标记和提示文本:

private void GridViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    if (args.Item is CustomDataObject dataItem && args.ItemContainer is GridViewItem gridViewItem)
    {
        // 替换为你的禁用判断逻辑
        bool needDisable = dataItem.Views < 100;
        
        gridViewItem.IsEnabled = !needDisable;
        dataItem.IsDisabled = needDisable;
        dataItem.DisabledToolTipText = "该项浏览量不足,无法交互";
    }
}

方法二:使用转换器绑定GridViewItem状态(无需修改数据源)

如果不想修改数据源,可以通过转换器绑定GridViewItem的IsEnabled状态,动态控制覆盖层的可用性:

1. 创建布尔反转转换器

public class BoolNegationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return !(value is bool b && b);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return !(value is bool b && b);
    }
}

2. 更新DataTemplate

引用转换器并绑定覆盖层的属性:

<Page.Resources>
    <local:BoolNegationConverter x:Key="BoolNegationConverter"/>
</Page.Resources>

<DataTemplate x:Key="ImageTextTemplate" x:DataType="local1:CustomDataObject">
    <Grid AutomationProperties.Name="{x:Bind Title}" Width="280">
        <Border 
            Background="Transparent"
            IsHitTestVisible="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType=GridViewItem}, Converter={StaticResource BoolNegationConverter}}"
            ToolTipService.ToolTip="该项已禁用,无法点击">
        </Border>

        <!-- 原有布局内容不变 -->
    </Grid>
</DataTemplate>

3. 保持原有禁用逻辑

在ContainerContentChanging中正常禁用GridViewItem即可,无需额外修改数据源:

private void GridViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    if (args.Item is CustomDataObject dataItem && args.ItemContainer is GridViewItem gridViewItem)
    {
        gridViewItem.IsEnabled = !(dataItem.Views < 100);
    }
}

内容的提问来源于stack exchange,提问作者rsp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:43:14