Legends are not getting color

Sep 20, 2013 at 2:22 PM
Hi, I am creating a multiline chart with custom datapoint, tool tip & color. I know binding in setter is not allowed. So I tried all the workaround but nothing works for me. Below given is whole code to regenerate my problem.

Image

MainPage.xaml
<Page.Resources>
    <Style TargetType="charting:DataPoint" x:Key="MyDataPointStyle">
            <Setter Property="Width" Value="17" />
            <Setter Property="Height" Value="17" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="charting:DataPoint">
                        <Grid>
                            <ToolTipService.ToolTip>
                                <ContentControl>
                                    <TextBlock TextAlignment="Center">
                                        <Run Text="{Binding SeriesName}" />
                                        <LineBreak />
                                        <Run Text="{Binding Value}" />
                                    </TextBlock>
                                </ContentControl>
                            </ToolTipService.ToolTip>
                            <Ellipse Fill="{Binding Color}" Stroke="{Binding Color}" StrokeThickness="3" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    <Style TargetType="Rectangle" x:Key="legendRectangleStyle">
            <!-- Both Not Working
            
            <Setter Property="local:SetterValueBindingHelper.PropertyBinding">
                <Setter.Value>
                    <local:SetterValueBindingHelper
                    Type="Shape"
                    Property="Fill"
                    Binding="{Binding Color}"/>
                </Setter.Value>
            </Setter>
            <Setter Property="local:SetterValueBindingHelper.PropertyBinding">
                <Setter.Value>
                    <local:SetterValueBindingHelper
                    Type="Shape"
                    Property="Stroke"
                    Binding="{Binding Color}"/>
                </Setter.Value>
            </Setter>
            
            =========================================================================
            
            <Setter Property="local:BindingBuilder.LegendColor" Value="Color" />
            -->
        </Style>

    <Style TargetType="charting:LegendItem" x:Key="legendItemStyle">
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="charting:LegendItem">
                        <Grid>
                            <StackPanel Orientation="Horizontal">
                                
                                <!-- Both Not Working
                                <Rectangle Width="8" Height="8" Fill="{Binding Color}" Stroke="{Binding Color}" StrokeThickness="1"  Margin="0,0,3,0" />
                                <Rectangle Width="8" Height="8" Style="{StaticResource legendRectangleStyle}" StrokeThickness="1"  Margin="0,0,3,0" />
                                -->
                                
                                <!-- Working -->
                                
                                <Rectangle Width="8" Height="8" Fill="Aqua" Stroke="Aqua" StrokeThickness="1"  Margin="0,0,3,0" />
                                <datavis:Title Content="{TemplateBinding Content}" />
                            </StackPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
</Page.Resources>

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <charting:Chart x:Name="LineChart" Title="Line Chart" Margin="70,0"/>
</Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
    int count = 5;
    private Random _random = new Random();
    List<string> colors = new List<string>();
    DispatcherTimer timer = new DispatcherTimer();

    public MainPage()
        {
            this.InitializeComponent();
        }

    protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            LineSeries line;
            GenerateColors(count);
            for (int i = 0; i < count; i++)
            {
                line = new LineSeries();
                line.Title = string.Format("Line [{0}]", i.ToString());
                line.IndependentValueBinding = GetBinding("Name");
                line.DependentValueBinding = GetBinding("Value");
                line.DataPointStyle = this.Resources["MyDataPointStyle"] as Style;
                line.LegendItemStyle = this.Resources["legendItemStyle"] as Style;
                line.Background = GetColorBrush(i);
                line.ItemsSource = GetItems(i);
                this.LineChart.Series.Add(line);
            }

            timer.Interval = TimeSpan.FromMilliseconds(1);
            timer.Tick += timer_Tick;
            timer.Start();
        }

    void timer_Tick(object sender, object e)
        {
            timer.Stop();
            for (int i = 0; i < count; i++)
            {
                ((LineSeries)LineChart.Series[i]).Background = GetColorBrush(i);
            }
        }

    private Binding GetBinding(string PropName)
        {
            Binding bind = new Binding();
            bind.Path = new PropertyPath(PropName);
            return bind;
        }

    private SolidColorBrush GetColorBrush(int index)
        {
            var stringValue = colors[index].Replace("#", string.Empty);
            return new SolidColorBrush(Color.FromArgb(
              Byte.Parse(stringValue.Substring(0, 2), NumberStyles.HexNumber),
              Byte.Parse(stringValue.Substring(2, 2), NumberStyles.HexNumber),
              Byte.Parse(stringValue.Substring(4, 2), NumberStyles.HexNumber),
              Byte.Parse(stringValue.Substring(6, 2), NumberStyles.HexNumber)));
        }

    private List<NameValueItem> GetItems(int i)
        {
            List<NameValueItem> items = new List<NameValueItem>();
            items.Add(new NameValueItem { Name = "Test1", Value = _random.Next(10, 100), Color = GetColorBrush(i), SeriesName = "Population " + i.ToString() });
            items.Add(new NameValueItem { Name = "Test2", Value = _random.Next(10, 100), Color = GetColorBrush(i), SeriesName = "Population " + i.ToString() });
            items.Add(new NameValueItem { Name = "Test3", Value = _random.Next(10, 100), Color = GetColorBrush(i), SeriesName = "Population " + i.ToString() });
            items.Add(new NameValueItem { Name = "Test4", Value = _random.Next(10, 100), Color = GetColorBrush(i), SeriesName = "Population " + i.ToString() });
            items.Add(new NameValueItem { Name = "Test5", Value = _random.Next(10, 100), Color = GetColorBrush(i), SeriesName = "Population " + i.ToString() });

            return items;
        }

    private void GenerateColors(int count)
        {
            for (int i = 0; i < count; i++)
            {
                colors.Add(Color.FromArgb(255, (byte)_random.Next(256), (byte)_random.Next(256), (byte)_random.Next(256)).ToString());
            }
        }
}

public class NameValueItem
{
    public string Name { get; set; }
    public int Value { get; set; }
    public SolidColorBrush Color { get; set; }
    public string SeriesName { get; set; }
    public string ColorString { get; set; }
}
Due to character limit I can't post BindingBuilder.cs please check out that class here
Coordinator
Sep 20, 2013 at 4:30 PM
Edited Sep 20, 2013 at 4:30 PM
Have you checked what the DataContext in your LegendItem was? Do you see any binding errors in VS output window?
Sep 21, 2013 at 6:00 AM
Edited Sep 21, 2013 at 6:05 AM
I am getting this binding error repeatedly.
Error: BindingExpression path error: 'Color' property not found on 'WinRTXamlToolkit.Controls.DataVisualization.Charting.LineDataPoint'. BindingExpression: Path='Color' DataItem='WinRTXamlToolkit.Controls.DataVisualization.Charting.LineDataPoint'; target element is 'Windows.UI.Xaml.Shapes.Rectangle' (Name='null'); target property is 'Fill' (type 'Brush')
Error: BindingExpression path error: 'Color' property not found on 'WinRTXamlToolkit.Controls.DataVisualization.Charting.LineDataPoint'. BindingExpression: Path='Color' DataItem='WinRTXamlToolkit.Controls.DataVisualization.Charting.LineDataPoint'; target element is 'Windows.UI.Xaml.Shapes.Rectangle' (Name='null'); target property is 'Stroke' (type 'Brush')
DataContext of LegendItem is null, so I tried set DataContext in tick event of timer & it's working. Though I am confused why I need to use timer to apply color to lines & legends.

Updated tick event.
void timer_Tick(object sender, object e)
{
    timer.Stop();
    for (int i = 0; i < count; i++)
    {
        ((LineSeries)LineChart.Series[i]).Background = GetColorBrush(i);
        ((ContentControl)((LineSeries)LineChart.Series[i]).LegendItems.FirstOrDefault()).DataContext = GetItems(i)[i];
    }
}
Also if I use Task.Delay(1), then I don't have to use timer. Why is it so?
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    LineSeries line;
    GenerateColors(count);
    for (int i = 0; i < count; i++)
    {
        line = new LineSeries();
        line.Title = string.Format("Line [{0}]", i.ToString());
        line.IndependentValueBinding = GetBinding("Name");
        line.DependentValueBinding = GetBinding("Value");
        line.DataPointStyle = this.Resources["MyDataPointStyle"] as Style;
        line.LegendItemStyle = this.Resources["legendItemStyle"] as Style;
        line.Background = GetColorBrush(i);
        line.ItemsSource = GetItems(i);
        this.LineChart.Series.Add(line);
    }

    await Task.Delay(1);   //USING DELAY I AM GETTING COLOR "WHY" ???

    for (int i = 0; i < count; i++)
    {
        ((ContentControl)((LineSeries)LineChart.Series[i]).LegendItems.FirstOrDefault()).DataContext = GetItems(i)[i];
        ((LineSeries)LineChart.Series[i]).Background = GetColorBrush(i);
    }

    timer.Interval = TimeSpan.FromMilliseconds(1);
    timer.Tick += timer_Tick;
    //timer.Start();   NO TIMER
} 
Coordinator
Sep 23, 2013 at 11:23 PM
I can see if the code for the charts has some bug that prevents the LegendItem DataContext from being set to the data. Maybe it's by design? As soon as I get some time to sit and play with the toolkit.
Sep 24, 2013 at 7:02 AM
Ok thanks a lot Filip for your kind help, I am facing one more issue have you checked that?
Sep 22, 2014 at 11:45 AM
Marked as answer by xyzzer on 9/22/2014 at 2:52 PM