private void CreateDataPointGroupBindings(DataPointGroup dataPointGroup)
        {
            var groupBinding = new Binding();

            groupBinding.Source = this;
            groupBinding.Mode   = BindingMode.TwoWay;
            groupBinding.Path   = new PropertyPath("SelectedItem");
            BindingOperations.SetBinding(dataPointGroup, DataPointGroup.SelectedItemProperty, groupBinding);
        }
        private void CreateDataPointBindings(DataPoint datapoint, DataPointGroup dataPointGroup)
        {
            //Sende an Datapoints the maximalvalue des Charts mit (wichtig in clustered Column chart)
            var maxDataPointValueBinding = new Binding();

            maxDataPointValueBinding.Source = this;
            maxDataPointValueBinding.Mode   = BindingMode.OneWay;
            maxDataPointValueBinding.Path   = new PropertyPath("MaxDataPointValue");
            BindingOperations.SetBinding(datapoint, DataPoint.MaxDataPointValueProperty, maxDataPointValueBinding);

            //Sende den Datapoints the höchste Summe einer DataPointGroup mit (wichtig für stacked chart)
            var maxDataPointGroupSumBinding = new Binding();

            maxDataPointGroupSumBinding.Source = this;
            maxDataPointGroupSumBinding.Mode   = BindingMode.OneWay;
            maxDataPointGroupSumBinding.Path   = new PropertyPath("MaxDataPointGroupSum");
            BindingOperations.SetBinding(datapoint, DataPoint.MaxDataPointGroupSumProperty, maxDataPointGroupSumBinding);

            //Sende den Datapoint die Summe seiner Datagroup
            var sumBinding = new Binding();

            sumBinding.Source = dataPointGroup;
            sumBinding.Mode   = BindingMode.OneWay;
            sumBinding.Path   = new PropertyPath("SumOfDataPointGroup");
            BindingOperations.SetBinding(datapoint, DataPoint.SumOfDataPointGroupProperty, sumBinding);

            var selectionBinding = new Binding();

            selectionBinding.Source = dataPointGroup;
            selectionBinding.Mode   = BindingMode.TwoWay;
            selectionBinding.Path   = new PropertyPath("SelectedItem");
            BindingOperations.SetBinding(datapoint, DataPoint.SelectedItemProperty, selectionBinding);

            var selectedBrushBinding = new Binding();

            selectedBrushBinding.Source = this;
            selectedBrushBinding.Mode   = BindingMode.OneWay;
            selectedBrushBinding.Path   = new PropertyPath("SelectedBrush");
            BindingOperations.SetBinding(datapoint, DataPoint.SelectedBrushProperty, selectedBrushBinding);

            //tooltip format (may change sometimes)
            var tooltipFormatBinding = new Binding();

            tooltipFormatBinding.Source = this;
            tooltipFormatBinding.Mode   = BindingMode.OneWay;
            tooltipFormatBinding.Path   = new PropertyPath("ToolTipFormat");
            BindingOperations.SetBinding(datapoint, DataPoint.ToolTipFormatProperty, tooltipFormatBinding);
        }
        private void UpdateGroupedSeries()
        {
            // data validation
            this.Exceptions.Clear();

            // ensure that caption of series is not null, otherwise all other series would be ignored (data from the same series are collection to the same datapointgroup)
            if (this.Series.Any(series => string.IsNullOrEmpty(series.SeriesTitle)))
            {
                Exceptions.Add("Series with empty caption cannot be used.");
            }

            //ensure that each series has a different name
            if (this.Series.GroupBy(series => series.SeriesTitle).Any(group => group.Count() > 1))
            {
                Exceptions.Add("Series with duplicate name cannot be used.");
            }

            if (!HasExceptions)
            {
                List <DataPointGroup> result = new List <DataPointGroup>();
                try
                {
                    if (GetIsRowColumnSwitched())
                    {
                        ///sammle erst alle Gruppen zusammen
                        foreach (ChartSeries initialSeries in this.Series)
                        {
                            int itemIndex = 0;
                            foreach (var seriesItem in initialSeries.Items)
                            {
                                string         seriesItemCaption = GetPropertyValue(seriesItem, initialSeries.DisplayMember); //Security
                                DataPointGroup dataPointGroup    = result.Where(group => group.Caption == seriesItemCaption).FirstOrDefault();
                                if (dataPointGroup == null)
                                {
                                    dataPointGroup = new DataPointGroup(this, seriesItemCaption, this.Series.Count > 1 ? true : false);
                                    dataPointGroup.PropertyChanged += dataPointGroup_PropertyChanged;
                                    result.Add(dataPointGroup);

                                    CreateDataPointGroupBindings(dataPointGroup);

                                    int seriesIndex = 0;
                                    foreach (ChartSeries allSeries in this.Series)
                                    {
                                        DataPoint datapoint = new DataPoint(this);
                                        datapoint.SeriesCaption    = allSeries.SeriesTitle;
                                        datapoint.ValueMember      = allSeries.ValueMember;
                                        datapoint.DisplayMember    = allSeries.DisplayMember;
                                        datapoint.ItemBrush        = this.Series.Count == 1 ? GetItemBrush(itemIndex) : GetItemBrush(seriesIndex); //if only one series, use different color for each datapoint, if multiple series we use different color for each series
                                        datapoint.PropertyChanged += groupdItem_PropertyChanged;

                                        CreateDataPointBindings(datapoint, dataPointGroup);

                                        dataPointGroup.DataPoints.Add(datapoint);
                                        seriesIndex++;
                                    }
                                    itemIndex++;
                                }
                            }
                        }

                        ///gehe alle Series durch (Security, Naming etc.)
                        foreach (ChartSeries series in this.Series)
                        {
                            foreach (var seriesItem in series.Items)
                            {
                                string seriesItemCaption = GetPropertyValue(seriesItem, series.DisplayMember); //Security

                                //finde die gruppe mit dem Namen
                                DataPointGroup addToGroup = result.Where(group => group.Caption == seriesItemCaption).FirstOrDefault();

                                //finde in der Gruppe
                                DataPoint groupdItem = addToGroup.DataPoints.Where(item => item.SeriesCaption == series.SeriesTitle).FirstOrDefault();
                                groupdItem.ReferencedObject = seriesItem;
                            }
                        }
                    }
                    else
                    {
                        foreach (ChartSeries initialSeries in this.Series)
                        {
                            //erstelle für jede Series einen DataPointGroup, darin wird dann für jedes Item in jeder Serie ein DataPoint angelegt
                            DataPointGroup dataPointGroup = new DataPointGroup(this, initialSeries.SeriesTitle, this.Series.Count > 1 ? true : false);
                            dataPointGroup.PropertyChanged += dataPointGroup_PropertyChanged;
                            result.Add(dataPointGroup);

                            CreateDataPointGroupBindings(dataPointGroup);

                            //stelle nun sicher, dass alle DataPointGruppen die gleichen Datapoints hat
                            foreach (ChartSeries allSeries in this.Series)
                            {
                                int seriesIndex = 0;
                                foreach (var seriesItem in allSeries.Items)
                                {
                                    string    seriesItemCaption = GetPropertyValue(seriesItem, initialSeries.DisplayMember); //Security
                                    DataPoint existingDataPoint = dataPointGroup.DataPoints.Where(datapoint => datapoint.SeriesCaption == seriesItemCaption).FirstOrDefault();
                                    if (existingDataPoint == null)
                                    {
                                        DataPoint datapoint = new DataPoint(this);
                                        datapoint.SeriesCaption    = seriesItemCaption;
                                        datapoint.ValueMember      = allSeries.ValueMember;
                                        datapoint.DisplayMember    = allSeries.DisplayMember;
                                        datapoint.ItemBrush        = GetItemBrush(seriesIndex);
                                        datapoint.PropertyChanged += groupdItem_PropertyChanged;

                                        CreateDataPointBindings(datapoint, dataPointGroup);

                                        dataPointGroup.DataPoints.Add(datapoint);
                                    }
                                    seriesIndex++;
                                }
                            }
                        }

                        ///gehe alle Series durch (Security, Naming etc.)
                        foreach (ChartSeries series in this.Series)
                        {
                            foreach (var seriesItem in series.Items)
                            {
                                //finde die gruppe mit dem Namen
                                DataPointGroup addToGroup = result.Where(group => group.Caption == series.SeriesTitle).FirstOrDefault();

                                //finde in der Gruppe das richtige Element
                                string seriesItemCaption = GetPropertyValue(seriesItem, series.DisplayMember); //Security

                                DataPoint groupdItem = addToGroup.DataPoints.Where(item => item.SeriesCaption == seriesItemCaption).FirstOrDefault();
                                groupdItem.ReferencedObject = seriesItem;
                            }
                        }
                    }
                }
                catch
                {
                }

                //finished, copy all to the array
                groupedSeries.Clear();
                foreach (var item in result)
                {
                    groupedSeries.Add(item);
                }

                UpdateColorsOfDataPoints(); // this gets run one time for each series

                chartLegendItems.Clear();
                DataPointGroup firstgroup = groupedSeries.FirstOrDefault();
                if (firstgroup != null)
                {
                    foreach (DataPoint dataPoint in firstgroup.DataPoints)
                    {
                        ChartLegendItemViewModel legendItem = new ChartLegendItemViewModel();

                        var captionBinding = new Binding();
                        captionBinding.Source = dataPoint;
                        captionBinding.Mode   = BindingMode.OneWay;
                        captionBinding.Path   = new PropertyPath("SeriesCaption");
                        BindingOperations.SetBinding(legendItem, ChartLegendItemViewModel.CaptionProperty, captionBinding);

                        var brushBinding = new Binding();
                        brushBinding.Source = dataPoint;
                        brushBinding.Mode   = BindingMode.OneWay;
                        brushBinding.Path   = new PropertyPath("ItemBrush");
                        BindingOperations.SetBinding(legendItem, ChartLegendItemViewModel.ItemBrushProperty, brushBinding);

                        chartLegendItems.Add(legendItem);
                    }
                }

                RecalcMaxDataPointValue(); //GA fix issue with max value in second group not being picked up add line
                RecalcSumOfDataPointGroup();

                if (_isGAMultipleSeriesChart)
                {
                    GACopyPointsForLineGraph(groupedSeries);
                }
            }
        }