Search code examples
c#wpfshapesredraw

WPF derived Shape triggering redraw on property change


I have a circular progress bar, which I have implemented as a class derived from Shape. I added DependencyProperties for all my properties that I need to bind. Property Value represents the progress. I overrided DefiningGeometry.

Now I want to get the progress bar to reflect to change when Value changes. My current approach is to register a PropertyChangedCallback on the DepencencyProperties that fires shape.InvalidateVisual().

This works fine, unless I have a Tooltip over my progress bar. A Timer increments Value, and the the Tooltip flickers once.

What would be the right way to get the shape updated?


Solution

  • It turned out that the flicker was triggered by an extended ObservableCollection that would would generate a NotifyCollectionChangedAction.Reset event that triggered a redraw of all items in the ItemsControl containing the Shapes.

    Following How to properly refresh a custom shape in WPF? I improved my DepependecyProperty to:

        public static readonly DependencyProperty StartProperty =
            DependencyProperty.Register(
                "Start",
                typeof(double),
                typeof(CircleSegment),
                new FrameworkPropertyMetadata(
                    0.0,
                    FrameworkPropertyMetadataOptions.AffectsRender));
    
        /// <summary>
        /// Start of the Segment. 0 is top (12 o'clock), 0.25 is right (3 o'clock), 0.25 is bottom (6 o'clock), 0.75 is left (9 o'clock).
        /// Painting is always Clockwise from Start to End.
        /// </summary>
        [TypeConverter(typeof(LengthConverter))]
        public double Start
        {
            get { return (double)GetValue(StartProperty); }
            set { SetValue(StartProperty, value); }
        }