开发者

Notification when rendering a Visual in WPF is complete

开发者 https://www.devze.com 2023-01-15 20:38 出处:网络
Is there a way to get notified (e.g., by an event) when a Visual开发者_JAVA百科 has been (re-)rendered?

Is there a way to get notified (e.g., by an event) when a Visual开发者_JAVA百科 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!


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.


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.


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).


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...);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消