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
相关产品推荐
相关产品推荐

