/// <summary> /// This is used to redraw only once instead of on every property change. /// </summary> internal void ScheduleRedraw() { if (!_redrawPending) // This ensures that the "BeginInvoke" method is only called once, and it is not called again until its delegate has been executed. { if (_isLoaded) { _redrawPending = true; // We use a dispatcher to avoid redrawing every time that a dependency property is set // (the result is as if we waited for the last property to be set). We use "INTERNAL_DispatcherHelpers.QueueAction" // instead of "Dispatcher.BeginInvoke" because it has better performance than calling Dispatcher.BeginInvoke directly. INTERNAL_DispatcherHelpers.QueueAction(() => { _redrawPending = false; // We check whether the Shape is visible in the HTML DOM tree, because if the HTML canvas is hidden // (due to a "Dispay:none" on one of the ancestors), we cannot draw on it // (this can be seen by hiding a canvas, drawing, and then showing it: it will appear empty): if (INTERNAL_VisibilityChangedNotifier.IsElementVisible(this)) { Redraw(); } else { _redrawWhenBecomeVisible = true; } }); } } }
void ScheduleRefresh() { if (!_refreshPending) // This ensures that the "BeginInvoke" method is only called once, and it is not called again until its delegate has been executed. { _refreshPending = true; INTERNAL_DispatcherHelpers.QueueAction(() => // We use a dispatcher to avoid refreshing every time (the result is as if we waited for the last change to be done before the thread is free). We use "INTERNAL_DispatcherHelpers.QueueAction" instead of "Dispatcher.BeginInvoke" because it has better performance than calling Dispatcher.BeginInvoke directly. { _refreshPending = false; Refresh(); }); } }
/// <summary> /// This is used to redraw only once instead of on every property change. /// </summary> internal void ScheduleRedraw() { if (!_redrawPending) // This ensures that the "BeginInvoke" method is only called once, and it is not called again until its delegate has been executed. { if (INTERNAL_VisualTreeManager.IsElementInVisualTree(this)) { _redrawPending = true; INTERNAL_DispatcherHelpers.QueueAction(() => // We use a dispatcher to avoid redrawing every time that a dependency property is set (the result is as if we waited for the last property to be set). We use "INTERNAL_DispatcherHelpers.QueueAction" instead of "Dispatcher.BeginInvoke" because it has better performance than calling Dispatcher.BeginInvoke directly. { _redrawPending = false; // We check whether the Shape is visible in the HTML DOM tree, because if the HTML canvas is hidden (due to a "Dispay:none" on one of the ancestors), we cannot draw on it (this can be seen by hiding a canvas, drawing, and then showing it: it will appear empty): if (INTERNAL_VisibilityChangedNotifier.IsElementVisible(this)) { Redraw(); // Stop listening to the ancestors' Visibility_Changed, if it was listening: if (_isListeningToAncestorsVisibilityChanged) { INTERNAL_VisibilityChangedNotifier.StopListeningToAncestorsVisibilityChanged(this); } _isListeningToAncestorsVisibilityChanged = false; } else { // We listen to the Visibility_Changed event of the ancestors so as try again if a parent becomes visible: if (!_isListeningToAncestorsVisibilityChanged) { _isListeningToAncestorsVisibilityChanged = true; INTERNAL_VisibilityChangedNotifier.StartListeningToAncestorsVisibilityChanged(this, () => { // Stop listening to the ancestors' Visibility_Changed: if (_isListeningToAncestorsVisibilityChanged) { INTERNAL_VisibilityChangedNotifier.StopListeningToAncestorsVisibilityChanged(this); } _isListeningToAncestorsVisibilityChanged = false; // Try again: ScheduleRedraw(); }); } } }); } } }