Extending RadChart for better MVVM binding

11 posts, 0 answers
  1. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 21 Feb 2011 Link to this post

    Hello,

    I'm trying to extend RadChart to use the same approach of MultChart, one Binding variable (IEnumerable of IEnumerable) and a datatemplate to define the data series.
    I would like to have no references of telerik in my viewmodel.
    The problem is that no matter what I bind to the chart control, I get a bar chart with unknown data :(
    Would you be so nice to take a look on it for me?
    The code I'm working with can be found here: [buggy code removed]

    Thank you in advance,
    André Carlucci


  2. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 22 Feb 2011 Link to this post

    I did it!

    RadChart with multichart binding using DataTemplateSelector working like a charm :)

    The main idea came from here: http://blog.thekieners.com/2010/02/07/databinding-multi-series-charts/

    Now I can declare a chart like this:

    <UserControl.Resources>
            <TelerikChart:SeriesTemplateSelector x:Key="chartTemplateSelector">
                <TelerikChart:SeriesTemplateSelector.BarChart>
                    <DataTemplate>
                        <TelerikChart:DataTemplateSeriesMapping>
                            <TelerikChart:DataTemplateSeriesMapping.SeriesDefinition>
                                <telerik:BarSeriesDefinition ShowItemLabels="False" />
                            </TelerikChart:DataTemplateSeriesMapping.SeriesDefinition>
     
                            <TelerikChart:DataTemplateSeriesMapping.ItemMappings>
                                <telerik:ItemMapping FieldName="Value" DataPointMember="YValue" />
                                <telerik:ItemMapping FieldName="Date" DataPointMember="XValue" />
                            </TelerikChart:DataTemplateSeriesMapping.ItemMappings>
     
                        </TelerikChart:DataTemplateSeriesMapping>
                    </DataTemplate>
                </TelerikChart:SeriesTemplateSelector.BarChart>
     
                <TelerikChart:SeriesTemplateSelector.LineChart>
                    <DataTemplate>
                        <TelerikChart:DataTemplateSeriesMapping>
                            <TelerikChart:DataTemplateSeriesMapping.SeriesDefinition>
                                <telerik:LineSeriesDefinition ShowItemLabels="False" />
                            </TelerikChart:DataTemplateSeriesMapping.SeriesDefinition>

                            <TelerikChart:DataTemplateSeriesMapping.ItemMappings>
                                <telerik:ItemMapping FieldName="Value" DataPointMember="YValue" />
                                <telerik:ItemMapping FieldName="Date" DataPointMember="XValue" />
                            </TelerikChart:DataTemplateSeriesMapping.ItemMappings>
     
                        </TelerikChart:DataTemplateSeriesMapping>
                    </DataTemplate>
                </TelerikChart:SeriesTemplateSelector.LineChart>
            </TelerikChart:SeriesTemplateSelector>
     
        </UserControl.Resources>

         <TelerikChart:MvvmRadChart SeriesSource="{Binding Curves}"
                                    SeriesTemplateSelector="{StaticResource chartTemplateSelector}" />


    And it works perfectly :)

    If you are interested in the source code just tell me and I will be more than happy to share.

    Cheers,

    André Carlucci 
  3. DevCraft banner
  4. Nathan
    Nathan avatar
    5 posts
    Member since:
    Dec 2010

    Posted 25 Feb 2011 Link to this post

    Very interested!

    Thanks, Andre
  5. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 01 Mar 2011 Link to this post

    Hi Nathan,

    I've uploaded the whole project to http://www.telerik.com/community/code-library/silverlight/chart.aspx, but it's not there yet. I guess they have some kind of moderation, so let's wait to see.

    Cheers,

    André Carlucci
  6. Vladimir Milev
    Admin
    Vladimir Milev avatar
    1061 posts

    Posted 03 Mar 2011 Link to this post

    Hello Andre,

    We just published the code library. Please, note our comments below the submission.

    Best wishes,
    Vladimir Milev
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  7. David
    David avatar
    2 posts
    Member since:
    Mar 2011

    Posted 22 Mar 2011 Link to this post

    Andre - really nice work, thanks!
    I am currently evaluating RadControls vs DevExpress right now and this is another reason to switch.

    Have you got the LegendLabel to be able to bind to a string value in the ChartInfo object? (that looks like what you were aiming for)

  8. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 22 Mar 2011 Link to this post

    Hi David,

    Yes I did.

    Here is one exemple of a DataTemplate with LegendLabel:

     <DataTemplate>
                        <TelerikChart:SeriesMappingWrapper ChartAreaName="chartArea" LegendLabel="{Binding Title}" >
     
                            <TelerikChart:SeriesMappingWrapper.SeriesDefinition>
                                <telerikCharting:BarSeriesDefinition ShowItemLabels="False" />
                            </TelerikChart:SeriesMappingWrapper.SeriesDefinition>
     
                            <TelerikChart:SeriesMappingWrapper.ItemMappings>
                                <telerikCharting:ItemMapping FieldName="Value" DataPointMember="YValue" />
                                <telerikCharting:ItemMapping FieldName="Date" DataPointMember="XValue" />
                            </TelerikChart:SeriesMappingWrapper.ItemMappings>
     
                        </TelerikChart:SeriesMappingWrapper>
                    </DataTemplate>

    Cheers :)
  9. David
    David avatar
    2 posts
    Member since:
    Mar 2011

    Posted 22 Mar 2011 Link to this post

    Yes, that's what I assumed, however it didn't work when I tried that. Perhaps you have code in the wrapper different to that you submitted to Telerik?

    You set the datacontext for each SeriesMappingWrapper in the CreateSeriesMapping and then grab the SeriesMapping straight out of it (in the code I have).
    templateSeriesMapping.DataContext = dataContextForSerie;
    return templateSeriesMapping.SeriesMapping;
     I would have thought that the act of setting the DataContext would cause the dependencyproperties to get their values (in particular the LegendLabel one) , but this doesn't seem to happen. I wonder if I need to force the binding update to happen somehow? (so that the OnLegendLabelChanged handler gets called)

    Apologies if this is a stupid question, i'm a little new to WPF.
  10. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 23 Mar 2011 Link to this post

    Hi David,

    The code I'm using is the same :(
    The thing is that when you set the dataContext, nothing really happens with the bindings at that moment.
    The bindings will be enforced once the control gets "loaded" or every time you call NotifyPropertyChanged event on the property you want to update.
    So, if you want to update the legend value after the object creation or at run time, make ChartInfo implement INotifyPropertyChanged interface and raise the PropertyChanged event with the LegendLabel property. It should work :)

    Cheers,

    André Carlucci
  11. Graham Ramsay
    Graham Ramsay avatar
    4 posts
    Member since:
    Oct 2006

    Posted 24 Mar 2011 Link to this post

    Love what you done with it so far, but I am running into a scoping problem around the DataContext I believe.  What I would like to do given the examples you've provided is to allow the ShowItemLabels property of the SeriesDefinition to be defined by a binding, but it does not work.   So similar to your template above, I'd like a template option with this XAML (you'll notice the only real significant change is that the ShowItemLabels property in the series wrapper is set to a binding rather than false):
     

     

     

     

     

     

    <TelerikChart:SeriesTemplateSelector.LineChart>
                        <DataTemplate>
                            <TelerikChart:SeriesMappingWrapper ChartAreaName="chartArea">
                                <TelerikChart:SeriesMappingWrapper.SeriesDefinition>
                                    <telerik:LineSeriesDefinition ShowItemLabels="{Binding DisplayDataLabels}"/>
                                </TelerikChart:SeriesMappingWrapper.SeriesDefinition>
      
                                <TelerikChart:SeriesMappingWrapper.ItemMappings>
                                    <telerik:ItemMapping FieldName="Value" DataPointMember="YValue" />
                                    <telerik:ItemMapping FieldName="TimePoint" DataPointMember="XValue" />
                                </TelerikChart:SeriesMappingWrapper.ItemMappings>
      
                            </TelerikChart:SeriesMappingWrapper>
                        </DataTemplate>
                    </TelerikChart:SeriesTemplateSelector.LineChart>

     

     

     

     

     

     


    But this doesn't work, as when the framework processes the Binding statement the DataContext scope is the whole ViewModel of my UI rather than the item in the collection that I am binding to the ItemSource.  Any ideas how to achieve this behavior?  In the end my requirement is to show series labels on some series, but not on every series.

    I've seen in your example you set the DataContext of the SeriesMappingWrapper to be the item in the collection you'd like for that series, and the ItemMappings DataContext scope seems correct as it does draw the data.  But can't figure out why the nested SeriesDefinition doesn't have same DataContext scope.

    My collection that is assigned to Chart ItemSource supports INotifyPropertyChanged and is a derived ObservableCollection, and each nested object in that collection also supports INotifyPropertyChanged and is a derived ObservableCollection.

    Thanks,

    Graham Ramsay
  12. Andre
    Andre avatar
    31 posts
    Member since:
    Feb 2011

    Posted 25 Mar 2011 Link to this post

    Hi Graham,

    I understand your problem.
    Since SeriesDefinition is also not a FrameworkElement, you cannot set its DataContext. I don't know exactly why it's not getting it from SeriesMappingWrapper :(

    One thing you can do is create another wrapper for the SeriesDefinition and use the same SeriesMappingWrapper strategy. Then you can set the SeriesDefinition DataContext programmatically. 

    It's too bad we have DependencyObjects instead of FrameworkElements everywhere, but that's a Telerik issue.

    Cheers,

    André
Back to Top
DevCraft banner