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

如何在整个WPF渲染周期内显示等待光标?

WPF全渲染周期等待光标设置可用事件列表

触发时机捕获事件

  • 自定义可触发重绘的依赖属性变更回调:比如你提到的边框StrokeWidth这类属性的PropertyChangedCallback,是最早捕获重绘触发的节点,可直接在回调内设置Mouse.OverrideCursor = Cursors.Wait。
  • 布局容器的FrameworkElement.SizeChanged事件:如果是容器尺寸变更触发的全量重绘,可通过AddHandler方法注册该事件,设置handledEventsToo为true避免内部控件吞掉事件。
  • 数据源变更事件:如果是层级数据源刷新触发的控件重绘,可监听对应数据源的INotifyPropertyChanged.PropertyChanged或INotifyCollectionChanged.CollectionChanged事件作为触发点。

渲染完成监听事件

  • UIElement.LayoutUpdated事件:该事件会在当前视觉树的Measure、Arrange流程全部完成后触发,是确认布局阶段结束的核心事件,需要搭配自定义标志位使用,避免多次触发逻辑。
  • CompositionTarget.Rendering事件:该事件会在WPF每帧渲染到屏幕前触发,要覆盖到最终屏幕输出环节,需要在LayoutUpdated触发后监听一次CompositionTarget.Rendering,再通过DispatcherPriority.Render优先级的调度恢复光标,就能保证等待光标覆盖全渲染周期。

示例代码

private bool _isWaitingForRender;

// 重绘触发时调用
private void StartWaitForRender()
{
    if (_isWaitingForRender) return;
    _isWaitingForRender = true;
    Mouse.OverrideCursor = Cursors.Wait;
    LayoutUpdated += OnLayoutCompleted;
}

private void OnLayoutCompleted(object sender, EventArgs e)
{
    LayoutUpdated -= OnLayoutCompleted;
    // 等待下一帧渲染完成后恢复光标
    CompositionTarget.Rendering += OnFrameRendered;
}

private void OnFrameRendered(object sender, EventArgs e)
{
    CompositionTarget.Rendering -= OnFrameRendered;
    // 确保渲染队列所有任务执行完成
    Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
    {
        Mouse.OverrideCursor = null;
        _isWaitingForRender = false;
    }));
}

注意:不要在MeasureOverride、ArrangeOverride方法内设置光标,两个方法会被频繁调用,容易导致光标闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:45:05