在 WPF 中渲染视觉对象完成时的通知

发布于 2024-09-19 10:16:28 字数 169 浏览 5 评论 0原文

当视觉对象被(重新)渲染时,有没有办法得到通知(例如,通过事件)?

基本上,每当视觉外观发生变化时,我都想截取屏幕截图。我假设渲染线程正在后台处理这个问题。

我试图避免定期抓取屏幕截图,因为我只对更改感兴趣(例如,将光标悬停在按钮上会改变其外观)。

任何提示都将受到高度赞赏!

Is there a way to get notified (e.g., by an event) when a Visual has been (re-)rendered?

Basically, I would like to take a screen shot whenever a Visual's appearance has changed. I assume the rendering thread is taking care of this in the background.

I am trying to avoid grabbing a screen shot periodically since I am only interested in changes (e.g., hovering the cursor over a button would change its appearance).

Any hint is highly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

惟欲睡 2024-09-26 10:16:28

我发现的最好方法是向布局根添加一个空面板,附加一个事件(例如尺寸更改)并从那里开始工作。

The best way I've found is to add an empty panel to the layout root attach an event like on size changed and work from there.

橪书 2024-09-26 10:16:28

此 MSDN 主题 提供了有关该主题的大量信息。基本上它并不是真正那样工作的,你会在那里找到确切的原因。

This MSDN thread provides quite a bit of information on the subject. Basically it doesn't really work that way and you'll find the exact reasons there.

瞎闹 2024-09-26 10:16:28

这在 WPF 中是不可能的。最好的办法是经常在内存中拍摄快照并将其与之前的进行比较。如果检测到差异,请保留快照。您可以使用 CompositionTarget.Rendering 为此举办的活动。只需确保不要在每个事件中都拍摄快照(因为它的调用频率与显卡交换其缓冲区的频率一样)。

This is not possible in WPF. Your best bet would be to take a snapshot in memory frequently and compare it with the previous. If you detect a diffrence, persist the snapshot. You could use the CompositionTarget.Rendering event for this. Just make sure that you don't take a snapshot in each event (since it is called as freuqently as the graphics card swaps its buffer).

月下客 2024-09-26 10:16:28

我遇到了类似的问题,我有一个 GridControl (devexpress WPF),每当重绘时我都需要对其执行操作。问题是我需要在完成填充网格并绘制所有元素后执行该操作。

这个解决方案是一种 hack,但实际上它 100% 有效,没有明显的缺点。它的工作原理是在可见状态发生变化后启动一个计时器,然后触发一个事件。

public ctor()
{
    Grid.IsVisibleChanged += TableOnIsVisibleChanged;
}


const int _msItTakesToDrawGrid = 5;
private Timer _timer;
private void TableOnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue != true || (bool)e.OldValue != false || _timer != null)
        return;


    _timer = new Timer { Interval = _msItTakesToDrawGrid };
    _timer.Elapsed += DoStuff;
    _timer.AutoReset = false;
    _timer.Start();
}

private void DoStuff(object sender, ElapsedEventArgs e)
{
    _timer.Stop();
    _timer= null;
    Dispatcher?.Invoke(stuff that needs to be done on the UI thread...);
}

I had a similar problem where I had a GridControl (devexpress WPF) that I needed to perform an action on whenever it was redrawn. The issue was I needed to perform the action AFTER it had finishes populating the grid and drawing all elements.

This solution is a hack however in practice it works 100% of the time with no apparent downsides. It works by simply starting a timer after the visible status has changed and firing an event afterwards.

public ctor()
{
    Grid.IsVisibleChanged += TableOnIsVisibleChanged;
}


const int _msItTakesToDrawGrid = 5;
private Timer _timer;
private void TableOnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue != true || (bool)e.OldValue != false || _timer != null)
        return;


    _timer = new Timer { Interval = _msItTakesToDrawGrid };
    _timer.Elapsed += DoStuff;
    _timer.AutoReset = false;
    _timer.Start();
}

private void DoStuff(object sender, ElapsedEventArgs e)
{
    _timer.Stop();
    _timer= null;
    Dispatcher?.Invoke(stuff that needs to be done on the UI thread...);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文