Can I sepecify the Legend's Stroke Dashstyle?

Mar 15, 2011 at 7:52 PM

I'm using the chart plotter object to display line graphs of raw data along with statistic values.  The idea is to keep all the related lines the same color and have different dash styles for each type of statistic, i.e. mean, max, etc.  This is all working but the dashstyle from the pen specified is not being translated to the the legend's stroke component.  Is there a way to do this? 

Thanks,
Mark

Oct 12, 2011 at 2:46 PM

I'd love to know how to do this one as well. 

Feb 6, 2014 at 8:51 PM
Edited Feb 6, 2014 at 9:17 PM
I was able to do this by modifying the source code, if you're courageous enough.

I don't know if all the changes I made are necessary, but this is what I did and it is working nicely. All of these files are in the project DynamicDataDisplay. Since most of the work was already done for me, I just had to find where "Stroke" and "StrokeThickness" were being set, and add "StrokeDashArray", "StrokeDashCap", "StrokeDashOffset", and "StrokeDashStyle" (the last of which actually encompasses StrokeDashArray and StrokeDashOffset, so if you set that it will set the others).

Pay attention to where I "Add" versus where I "replace".

LineGraph.cs:
        [...]
        // replace:
        private static IEnumerable<FrameworkElement> DefaultLegendItemsBuilder(IPlotterElement plotterElement)
        {
            LineGraph lineGraph = (LineGraph)plotterElement;

            Line line = new Line { X1 = 0, Y1 = 10, X2 = 20, Y2 = 0, Stretch = Stretch.Fill, DataContext = lineGraph };
            line.SetBinding(Line.StrokeProperty, "Stroke");
            line.SetBinding(Line.StrokeThicknessProperty, "StrokeThickness");
            line.SetBinding(Line.StrokeDashArrayProperty, "StrokeDashArray");
            line.SetBinding(Line.StrokeDashCapProperty, "StrokeDashCap");
            NewLegend.SetVisualContent(lineGraph, line);

            var legendItem = LegendItemsHelper.BuildDefaultLegendItem(lineGraph);
            yield return legendItem;
        }

        [...]
        // Add:

        /// <summary>
        /// Gets or sets the line dash array.
        /// </summary>
        /// <value>The line dash array.</value>
        public DoubleCollection StrokeDashArray
        {
            get { return LinePen.DashStyle.Dashes; }
            set
            {
                if (LinePen.DashStyle.Dashes != value)
                {
                    if (!LinePen.IsSealed)
                    {
                        LinePen.DashStyle.Dashes = value; InvalidateVisual();
                    }
                    else
                    {
                        Pen pen = LinePen.Clone();
                        pen.DashStyle.Dashes = value;
                        LinePen = pen;
                    }

                    RaisePropertyChanged("StrokeDashArray");
                }
            }
        }

        /// <summary>
        /// Gets or sets the line dash cap.
        /// </summary>
        /// <value>The line dash cap.</value>
        public PenLineCap StrokeDashCap
        {
            get { return LinePen.DashCap; }
            set
            {
                if (LinePen.DashCap != value)
                {
                    if (!LinePen.IsSealed)
                    {
                        LinePen.DashCap = value; InvalidateVisual();
                    }
                    else
                    {
                        Pen pen = LinePen.Clone();
                        pen.DashCap = value;
                        LinePen = pen;
                    }

                    RaisePropertyChanged("StrokeDashCap");
                }
            }
        }

        /// <summary>
        /// Gets or sets the line dash offset.
        /// </summary>
        /// <value>The line dash offset.</value>
        public double StrokeDashOffset
        {
            get { return LinePen.DashStyle.Offset; }
            set
            {
                if (LinePen.DashStyle.Offset != value)
                {
                    if (!LinePen.IsSealed)
                    {
                        LinePen.DashStyle.Offset = value; InvalidateVisual();
                    }
                    else
                    {
                        Pen pen = LinePen.Clone();
                        pen.DashStyle.Offset = value;
                        LinePen = pen;
                    }

                    RaisePropertyChanged("StrokeDashOffset");
                }
            }
        }

        /// <summary>
        /// Gets or sets the line dash style.
        /// </summary>
        /// <value>The line dash style.</value>
        public DashStyle StrokeDashStyle
        {
            get { return LinePen.DashStyle; }
            set
            {
                if (LinePen.DashStyle != value)
                {
                    if (!LinePen.IsSealed)
                    {
                        LinePen.DashStyle = value; InvalidateVisual();
                    }
                    else
                    {
                        Pen pen = LinePen.Clone();
                        pen.DashStyle = value;
                        LinePen = pen;
                    }

                    RaisePropertyChanged("StrokeDashStyle");
                }
            }
        }

LineLegendItem.xaml:
                <!-- Replace: -->
                <Line X1="3" X2="20" Y1="10" Y2="5" 
                      Stroke="{Binding Stroke}" 
                      StrokeThickness="{Binding StrokeThickness}" 
                      StrokeDashArray="{Binding Path=StrokeDashArray}" 
                      StrokeDashCap="{Binding Path=StrokeDashCap}"
                      StrokeDashOffset="{Binding Path=StrokeDashOffset}" />
PenDescription.cs:
        // replace:
        protected override void AttachCore(UIElement graph)
        {
            base.AttachCore(graph);
            LineGraph g = graph as LineGraph;
            if (g == null)
            {
                throw new ArgumentException("Pen description can only be attached to PointsGraph", "graph");
            }

            SetBinding(StrokeProperty, new Binding("Stroke") { Source = g });
            SetBinding(StrokeThicknessProperty, new Binding("StrokeThickness") { Source = g });
            SetBinding(StrokeDashArrayProperty, new Binding("StrokeDashArray") { Source = g });
            SetBinding(StrokeDashCapProperty, new Binding("StrokeDashCap") { Source = g });
            SetBinding(StrokeDashOffsetProperty, new Binding("StrokeDashOffset") { Source = g });
            SetBinding(StrokeDashStyleProperty, new Binding("StrokeDashStyle") { Source = g });
        }

        // add:
        public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register(
          "StrokeDashArray",
          typeof(DoubleCollection),
          typeof(PenDescription),
          new FrameworkPropertyMetadata(null));

        public PenLineCap StrokeDashCap
        {
            get { return (PenLineCap)GetValue(StrokeDashCapProperty); }
            set { SetValue(StrokeDashCapProperty, value); }
        }

        public static readonly DependencyProperty StrokeDashCapProperty = DependencyProperty.Register(
          "StrokeDashCap",
          typeof(PenLineCap),
          typeof(PenDescription),
          new FrameworkPropertyMetadata(null));

        public double StrokeDashOffset
        {
            get { return (double)GetValue(StrokeDashOffsetProperty); }
            set { SetValue(StrokeDashOffsetProperty, value); }
        }

        public static readonly DependencyProperty StrokeDashOffsetProperty = DependencyProperty.Register(
          "StrokeDashOffset",
          typeof(double),
          typeof(PenDescription),
          new FrameworkPropertyMetadata(0.0));

        public DashStyle StrokeDashStyle
        {
            get { return (DashStyle)GetValue(StrokeDashStyleProperty); }
            set { SetValue(StrokeDashStyleProperty, value); }
        }

        public static readonly DependencyProperty StrokeDashStyleProperty = DependencyProperty.Register(
          "StrokeDashStyle",
          typeof(DashStyle),
          typeof(PenDescription),
          new FrameworkPropertyMetadata(null));