Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

wpf databinding to observable collection not displaying in wpf chart

Posted on 2014-01-07
2
1,490 Views
Last Modified: 2014-01-08
Stuck on something that must be very basic.
I am databinding a wpf line chart to an observable collection.

in my custom class looks like

    public class InternalLoginClass
    {
        public MainWindow mainwindow;
        public MyControls.DataGrid DataGridBreakdown;
        public MyControls.DataGrid DataGridPerformance;
        public MyCharting.Chart ChartManagerBarPerc;
        public MyCharting.Chart ChartSectorTotalsBarchart;
        public MyCharting.Chart ChartTimeLineIndividual;
        public MyCharting.Chart ChartTimeLineTotals;
        public MyControls.TextBox textboxTotalPortfolioPL;

        public ObservableCollection<List<KeyValuePair<DateTime, double>>> timeLineDataSource { get; set; }


        public CurrentSelectedObject currentObject;

        BackgroundWorker backgroundWorkerTimeline;
        BackgroundWorker backgroundWorkerMainGrid;
        BackgroundWorker backgroundWorkerDatagridBreakdown;
        BackgroundWorker backgroundWorkerSectorBarchart;

  public InternalLoginClass()
        {

            //create background workers
                backgroundWorkerTimeline = new BackgroundWorker();
                backgroundWorkerTimeline.DoWork += backgroundWorkerTimeline_DoWork;

                timeLineDataSource = new ObservableCollection<List<KeyValuePair<DateTime, double>>>();

                 mainwindow = System.Windows.Application.Current.MainWindow as MainWindow;
                 currentObject = mainwindow.currentObject as CurrentSelectedObject;

                 ChartTimeLineIndividual = mainwindow.FindName("ChartTimeLineSectorTotals") as MyCharting.Chart;
                 ChartTimeLineIndividual.DataContext = timeLineDataSource;
}

Open in new window


then in a background thread I run this

                if (timeLineDataSource.Count != 11)
                {
                    //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                    //{
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                        timeLineDataSource.Add(new List<KeyValuePair<DateTime, double>>());
                    //}));

                }

                                using (SqlDataReader reader = command.ExecuteReader())
                                {
                                    while (reader.Read())
                                    {
                                        DateTime sqlTimestamp = reader.GetDateTime(0);
                                        decimal sqlPL = reader.GetDecimal(1);
                                        double sqlPLdouble = Convert.ToDouble(sqlPL);
                                        string sqlSec = reader.GetString(2);

                                            var targetDatasourceItem = timeLineDataSource[datasourceIndex];
                                            KeyValuePair<System.DateTime, double> curKVP = new KeyValuePair<DateTime, double>(sqlTimestamp, sqlPLdouble);
                                            
                                            if (!targetDatasourceItem.Contains(curKVP))
                                            {
                                                //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                                //{
                                                    timeLineDataSource[datasourceIndex].Add(curKVP);
                                                //}));
                                            }

                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            System.Windows.MessageBox.Show("error in CreateTimelineLineChart " + e);
                        }

Open in new window


basically I run a sql query, and for each row returned, I check to see if already in my observable collection, if not, then I add to collection.

This works just fine and each item is added to appropriate index of observable collection.
The problem is my graph does not show any data.

I am databinding like so

                    <chartingToolkit:Chart x:Name="ChartTimeLineSectorTotals"
						Margin="0,0,0,0"
						xml:lang="en-US"
                        Grid.Row="3" 
                        Grid.RowSpan="3"
                        RenderOptions.BitmapScalingMode="NearestNeighbor"
                        MouseLeftButtonUp="ChartTimeLineSectorTotals_MouseLeftButtonUp"
                        IsHitTestVisible="True">
                        <!--DataContext="{Binding Source={StaticResource ResourceKey=MyData}, Path=timeLineDataSource}"-->

                        <chartingToolkit:LineSeries Name="Energy"
                            Title="Energy"
                            ItemsSource="{Binding [0]}"
                            DependentValuePath="Value"
                            IndependentValuePath="Key"
                            IsSelectionEnabled="True" 
                            SelectionChanged="SectorTimeLineChart_SelectionChanged"
                            IsHitTestVisible="True"
                            PolylineStyle="{StaticResource DashedPolyLine}">

                            <chartingToolkit:LineSeries.DataPointStyle>
                                <Style TargetType="{x:Type chartingToolkit:LineDataPoint}">
                                <Setter Property="Background" Value="Yellow"/>
                                <Setter Property="Height" Value="Auto" />
                                <Setter Property="Width" Value="Auto"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type chartingToolkit:LineDataPoint}">
                                            <Grid x:Name="Root">
                                                    <TextBlock 
                                                        Name="Energy"
                                                        Foreground="Yellow" 
                                                        Background="Transparent"
                                                        FontSize="10"
                                                        Margin="0,0,50,0"
                                                        MouseEnter="TextBlock_MouseEnter"
                                                        MouseLeave="TextBlock_MouseLeave">
                                                            <TextBlock.Text>
                                                                <MultiBinding Converter="{StaticResource ResourceKey=timelineClassFormatter}"
                                                                              ConverterParameter="LABEL">
                                                                    <Binding Path="."/>
                                                                    <Binding Source="Energy"/>
                                                                <!--<Binding Source="{StaticResource ResourceKey=MyData}" Path="timeLineDataSource"/>-->
                                                            </MultiBinding>
                                                            </TextBlock.Text>
                                                </TextBlock>
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                                </Style>
                            </chartingToolkit:LineSeries.DataPointStyle>
                        </chartingToolkit:LineSeries>    

Open in new window


any ideas why nothing is being displayed in my graph?
I also checked my multivalueconverter and it never fires when I add one keyvaluepair of N index to my observable collection.

I get the feeling if I ADD a new list to the observable collection, everything works, but if I add a KeyValuePair to N item of a list, in the OC, then the converter never fires.

any help would be greatly appreciated.!
0
Comment
Question by:solarissf
2 Comments
 
LVL 13

Accepted Solution

by:
Naman Goel earned 500 total points
ID: 39765471
No charting tool can't take datasource as ObservableCollection<List<KeyValuePair<DateTime, double>>> type of object

even this should be ok ObservableCollection<KeyValuePair<DateTime, double>>

Adding a List inside ObservableCollection is creating problem for you

best approach is  you should have a custom collection.


namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        TimeLineCollection c = new TimeLineCollection();
        public Window1()
        {
            InitializeComponent();
            chartValues.ItemsSource = c;

            
        }
    }

   
    public class TimeLineCollection :ObservableCollection<TimeLine> // Extending from System.Collections.ObjectModel.Collection class
    {
        public TimeLineCollection() // Constructor to add TimeLine objects to the TimeLineCollection
        {
           
        }
    }

    public class TimeLine
    {
        public TimeLine(DateTime time, double value)    // Constructor
        {
            this.Time = time;
            this.Value = value;
        }
        public string Time                // Time Property
        {
            get;
            set;
        }
        public long Value                // Value Property
        {
            get;
            set;
        }
    }
}

Open in new window

0
 

Author Comment

by:solarissf
ID: 39765824
thank you!  that was the issue... the fact that I had an OC on a list.
Soon as I removed the list I could add individual points.

thanks again!
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question