You need to enable JavaScript to run this app. 如何配置XAML单元格模板,使SSN仅在Tooltip弹出时按需解密
优惠活动
大模型
产品
解决方案
定价
更多

如何配置XAML单元格模板,使SSN仅在Tooltip弹出时按需解密

实现方案

核心逻辑完全匹配需求:仅在Tooltip实际满足弹出条件时触发单条查询,绝不批量加载全量SSN数据,适配.NET Framework 4.5.2开发环境。

第一步:修改SSN列的XAML模板

原有DelayToolTip样式无需改动,仅调整SSN列CellTemplate内的Tooltip结构,添加命名控件方便后台更新文本,绑定Tooltip打开事件:

<DataGridTemplateColumn Header="SSN">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="Hidden"
                       Foreground="DarkOrange"
                       Background="Aquamarine"
                       Margin="3,1"
                       Style="{StaticResource DelayToolTip}"
                       Padding="3"
                       ToolTipOpening="SsnCell_ToolTipOpening">
                <TextBlock.ToolTip>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="SSN: "
                                   FontWeight="Bold" />
                        <!-- 给结果展示TextBlock加命名,方便后台赋值 -->
                        <TextBlock x:Name="SsnResultDisplay" Text="准备加载" />
                    </StackPanel>
                </TextBlock.ToolTip>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

第二步:添加后台事件处理逻辑

在当前UserControl的代码后置中实现以下逻辑,包含单条查询、线程安全缓存、后台异步执行、状态异常保护:

  1. 初始化线程安全缓存,仅存储用户实际触发过查询的SSN值,避免重复打库
  2. 在Tooltip触发打开时,先查缓存,未命中则后台调用解密存储过程
  3. 全程不操作非悬停行的SSN数据,严格满足禁止批量加载的要求
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

public partial class YourUserControl : UserControl
{
    // 线程安全的局部缓存,仅保留用户悬停触发过的SSN后四位,缓存生命周期随UserControl
    private readonly ConcurrentDictionary<int, string> _ssnLocalCache = new ConcurrentDictionary<int, string>();

    public YourUserControl()
    {
        InitializeComponent();
    }

    private async void SsnCell_ToolTipOpening(object sender, ToolTipEventArgs e)
    {
        // 获取当前触发行的绑定上下文
        var currentTextBlock = (TextBlock)sender;
        var currentPerson = (Person)currentTextBlock.DataContext;
        var tooltipRoot = (StackPanel)currentTextBlock.ToolTip;
        var resultDisplay = (TextBlock)tooltipRoot.FindName("SsnResultDisplay");
        var tooltipInstance = (ToolTip)currentTextBlock.ToolTip;

        // 标记Tooltip状态,避免查询返回时Tooltip已关闭导致的UI操作异常
        bool isTooltipClosed = false;
        void CloseHandler(object s, RoutedEventArgs args) => isTooltipClosed = true;
        tooltipInstance.Closed += CloseHandler;

        // 优先读缓存,避免重复查询
        if (_ssnLocalCache.TryGetValue(currentPerson.ID, out var cachedLast4))
        {
            if (!isTooltipClosed)
                resultDisplay.Text = $"**{cachedLast4}";
            tooltipInstance.Closed -= CloseHandler;
            return;
        }

        // 缓存未命中,先展示加载状态
        resultDisplay.Text = "正在加载...";

        try
        {
            // 后台线程执行数据库解密查询,不阻塞UI线程
            var last4 = await Task.Run(() =>
            {
                // 替换为你已写好的解密存储过程调用方法,传当前行的Person.ID作为参数
                return DecryptSsnStoredProc.GetSsnLast4ById(currentPerson.ID);
            });

            // 写入缓存
            _ssnLocalCache.TryAdd(currentPerson.ID, last4);

            // 回到UI线程更新展示
            if (!isTooltipClosed)
            {
                resultDisplay.Text = $"**{last4}";
            }
        }
        catch
        {
            if (!isTooltipClosed)
            {
                resultDisplay.Text = "信息加载失败";
            }
        }
        finally
        {
            tooltipInstance.Closed -= CloseHandler;
        }
    }
}

关键适配说明

  • 触发时机完全匹配你配置的延迟规则:ToolTipOpening事件仅在鼠标悬停满InitialShowDelay(1秒)、Tooltip即将真正弹出时触发,不会因为用户快速划过单元格就产生无意义查询
  • 严格遵守不批量加载的要求:全流程仅对用户悬停过的单个PersonID发起解密查询,其他行的加密SSN完全不读取,相比全量解密45分钟的性能损耗是数量级提升
  • 兼容.NET Framework 4.5.2:所用API均为该框架原生支持的能力,无需升级版本或引入第三方依赖
  • 异常保护逻辑覆盖了Tooltip提前关闭、数据库查询超时等常见场景,不会出现UI卡顿或运行时报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 08:27:04