Hello again,
I'm trying to figure out how to make the series lines dotted in a Silverlight xamWebChart. I have so far tried two approaches without much luck.
Firstly, I tried applying a dotted line style directly to the series object - I received the exception "Element is already the child of another element".
Then, I found an example that specified the following:
<igWebChart:XamWebChart.Resources>
<Style TargetType="{x:Type Line}">
<Setter Property="StrokeDashArray" Value="2,1" />
</Style>
</igWebChart:XamWebChart.Resources>
However, I receive the error that "Type" is not found.
Any insight would be appreciated. Thanks again!
the x:Type markup extension doesn't exist in Silverlight, only WPF. Try just TargetType="Line" although I'm not sure if the implicit style will work in this case or not. Let me know if it doesn't and I'll see if I can help.
^ Silverlight and recent versions of WPF will automatically try to convert string values into types without the need of a markup extension.
-Graham
Thanks for the solution Graham! If I did want to apply the style manually to each datapoint however, how would I do that? Setting each datapoint's style equal to the one in your xaml doesn't seem to do anything.
Seems to work for me either way. How are you setting the datapoints styles in your case? Anyway, you can use the version I posted as an implicit style as you originally had it configured, in any case.
This is basically how I'm doing it:
foreach (DataPoint point in series.DataPoints)
{
point.Style = (Style)Application.Current.Resources["dottedline"];
}
I'm not sure what's up. Are there some other settings that take precedence over defining a Style, like explicitly setting Fill or something?
I suspect you have your style defined at a lower level than App.xaml.
try: point.Style = (Style)Resources["dottedline"];
make sure that point.Style is not null after that line, in other words.
It works splendidly. The problem was that I had somehow undone my changes to the xaml for the style, and was using the old version instead of your new Workarounds version. You have more than answered my question, thank you sir.
Hi,
Could you explain how your scenario differs from this sample which shows all line segments as dotted for me:
App.xaml:
<Application.Resources> <Style x:Key="lineStyle" TargetType="Line"> <Setter Property="local:WorkArounds.StrokeDashArraySetter"> <Setter.Value> <local:StrokeDashArraySetter Value="5,1" /> </Setter.Value> </Setter> </Style> </Application.Resources>
MainPage.xaml:
<Grid x:Name="LayoutRoot" Background="White"> <igChart:XamWebChart x:Name="chart1" Loaded="chart1_Loaded"> <igChart:XamWebChart.Series> <igChart:Series ChartType="Line"> <igChart:Series.DataPoints> <igChart:DataPoint Label="A" Value="1" /> <igChart:DataPoint Label="B" Value="2" /> <igChart:DataPoint Label="C" Value="3" /> <igChart:DataPoint Label="D" Value="4" /> <igChart:DataPoint Label="E" Value="5" /> <igChart:DataPoint Label="F" Value="4" /> <igChart:DataPoint Label="G" Value="3" /> <igChart:DataPoint Label="H" Value="2" /> <igChart:DataPoint Label="I" Value="1" /> <igChart:DataPoint Label="J" Value="2" /> <igChart:DataPoint Label="K" Value="3" /> </igChart:Series.DataPoints> </igChart:Series> </igChart:XamWebChart.Series> </igChart:XamWebChart> </Grid>
Code behind:
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void chart1_Loaded(object sender, RoutedEventArgs e) { foreach (DataPoint point in chart1.Series[0].DataPoints) { point.Style = (Style)Application.Current.Resources["lineStyle"]; } } } public static class WorkArounds { public static readonly DependencyProperty StrokeDashArraySetterProperty = DependencyProperty.RegisterAttached( "StrokeDashArraySetter", typeof(StrokeDashArraySetter), typeof(WorkArounds), new PropertyMetadata(null, (o, e) => OnDataPointStylerChanged(o, e))); public static void SetStrokeDashArraySetter( DependencyObject target, StrokeDashArraySetter value) { target.SetValue(StrokeDashArraySetterProperty, value); } public static StrokeDashArraySetter GetStrokeDashArraySetter( DependencyObject target) { return (StrokeDashArraySetter)target .GetValue(StrokeDashArraySetterProperty); } private static void OnDataPointStylerChanged( DependencyObject o, DependencyPropertyChangedEventArgs e) { var oldValue = e.OldValue as StrokeDashArraySetter; var newValue = e.NewValue as StrokeDashArraySetter; if (oldValue != null) { oldValue.Detach(o); } if (newValue != null) { newValue.Attach(o); } } } public class StrokeDashArraySetter { public string Value { get; set; } private DependencyObject _owner; internal void Attach(DependencyObject o) { if (_owner != null) { Detach(_owner); } var dep = o; if (dep == null) { return; } _owner = dep; if (_owner is Shape) { var shape = _owner as Shape; if (Value == null) { return; } string[] vals = Value.Split(','); DoubleCollection coll = new DoubleCollection(); foreach (var val in vals) { double res; if (double.TryParse(val, out res)) { coll.Add(res); } } shape.StrokeDashArray = coll; } } internal void Detach(DependencyObject o) { _owner = null; } }
It's not null afterwards - and I did put that style in my app.xaml.
Something else interesting - if I place the style in <igWebChart:XamWebChart.Resources>, it only applies itself to the first line segment if it does not have a key name. Not really important, but I noticed it.
I only want to apply the dotted style to my series sometimes, so I need to be able to do it programmatically rather than having it explicitly set all the time. Sorry for the hassle, but I'm really hoping you can help me solve this. Thanks again.