This is a migrated thread and some comments may be shown as answers.

ChartDefaultView in DataTemplate

11 Answers 155 Views
Chart
This is a migrated thread and some comments may be shown as answers.
AdaDog
Top achievements
Rank 1
AdaDog asked on 05 Mar 2010, 04:21 PM
Does anyone have an example of a collection of charts in an ItemsControl?  I created one that renders the charts correctly, but ignores the ChartDefaultView.ChartArea AxisX/Y.

If you pull the ContentControl out of the DataTemplate and bind it to a single item, then the X and Y axes behave correctly.

 

    <ItemsControl Margin="5,20,5,5" ItemsSource="{Binding ChartSeriesViewModelCollection}">  
        <ItemsControl.ItemsPanel> 
            <ItemsPanelTemplate> 
                <UniformGrid Rows="2" Columns="3" /> 
            </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
        <ItemsControl.ItemTemplate> 
            <DataTemplate> 
                <ContentControl DataContext="{Binding}">  
                    <telerikChart:RadChart Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"   
                                                   ItemsSource="{Binding ChartSeries}" 
                                                   HorizontalAlignment="Stretch" 
                                                   VerticalAlignment="Stretch" > 
 
                        <telerikChart:RadChart.SeriesMappings> 
                            <telerikCharting:SeriesMapping> 
                                <telerikCharting:SeriesMapping.SeriesDefinition> 
                                    <telerikCharting:BarSeriesDefinition /> 
                                </telerikCharting:SeriesMapping.SeriesDefinition> 
 
                                <telerikCharting:SeriesMapping.GroupingSettings> 
                                            <telerikCharting:GroupingSettings ShouldCreateSeriesForLastGroup="False">  
                                                <telerikCharting:GroupingSettings.GroupDescriptors> 
                                                    <telerikCharting:ChartGroupDescriptor Member="GroupString" /> 
                                                </telerikCharting:GroupingSettings.GroupDescriptors> 
                                            </telerikCharting:GroupingSettings> 
                                        </telerikCharting:SeriesMapping.GroupingSettings> 
 
                                <telerikCharting:SeriesMapping.ItemMappings> 
                                    <telerikCharting:ItemMapping FieldName="Value" DataPointMember="YValue" /> 
                                    <telerikCharting:ItemMapping FieldName="LabelString" DataPointMember="XCategory" /> 
                                </telerikCharting:SeriesMapping.ItemMappings> 
 
                            </telerikCharting:SeriesMapping> 
                        </telerikChart:RadChart.SeriesMappings> 
 
                        <telerikChart:RadChart.DefaultView> 
                            <telerikCharting:ChartDefaultView> 
                                <telerikCharting:ChartDefaultView.ChartArea> 
                                    <telerikCharting:ChartArea > 
                                        <telerikCharting:ChartArea.AxisX> 
                                            <telerikCharting:AxisX TicksDistance="30" LabelRotationAngle="45" Title="X Axis Title" /> 
                                        </telerikCharting:ChartArea.AxisX> 
                                        <telerikCharting:ChartArea.AxisY> 
                                            <telerikCharting:AxisY AutoRange="False" MinValue="100" MaxValue="200" Step="5" 
                                          DefaultLabelFormat="0" Title="Ampere [A]"/>  
                                        </telerikCharting:ChartArea.AxisY> 
 
                                    </telerikCharting:ChartArea> 
                                </telerikCharting:ChartDefaultView.ChartArea> 
                                        <telerikCharting:ChartDefaultView.ChartLegend> 
                                            <telerikCharting:ChartLegend x:Name="chartLegend" Header="Legend"   
                                                                         UseAutoGeneratedItems="True" /> 
                                        </telerikCharting:ChartDefaultView.ChartLegend> 
 
                            </telerikCharting:ChartDefaultView> 
                        </telerikChart:RadChart.DefaultView> 
 
                    </telerikChart:RadChart> 
                </ContentControl> 
                  
            </DataTemplate> 
              
        </ItemsControl.ItemTemplate> 
    </ItemsControl> 
 

11 Answers, 1 is accepted

Sort by
0
Giuseppe
Telerik team
answered on 09 Mar 2010, 12:28 PM
Hello Doug,

Indeed we were able to reproduce the problematic behavior and we must admit we were quite puzzled to do so. Our developers immediately started to investigate the issue and unfortunately found out that the problem seems to be related to the handling of DataTemplates in WPF itself and not to the RadChart control.

We have attached a sample application that demonstrates the same problem can be observed in a scenario that does not contain any chart instances. You can use the VS debugger and the "Make Object ID" tool to verify the following:

Expected behavior:
  • One CustomDependencyObject instance should be created in the CustomContentControl constructor and TestPropertyChanged callback should be called as well.
  • Another CustomDependencyObject instance should be created according to the XAML declaratation and TestPropertyChanged callback should be called again (this instance is correctly set to CustomContentControl.TestProperty).
  • CustomDependencyObject.CustomStringProperty should be set on the second CustomDependencyObject instance.

Observed behavior:
  • One CustomDependencyObject instance is created in the CustomContentControl constructor and TestPropertyChanged callback should be called as well.
  • TestPropertyChanged callback is not raised again according to the XAML declaration (i.e. CustomContentControl.TestProperty is not changed).
  • CustomDependencyObject.CustomStringProperty is set on a second "ghost" instance of CustomDependencyObject that is not the same as the one set in the CustomContentControl (i.e. there are two CustomDependencyObject instances created but one of them erroneously is not set to the CustomContentControl.TestProperty and that is why its settings are lost).

Unfortunately we cannot suggest you a workaround for this scenario besides setting the axis properties in code-behind (you will probably need to create a derived ItemsControl class and use its PrepareContainerForItemOverride(...) method to do so).


Regards,
Manuel
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
emi
Top achievements
Rank 1
answered on 16 Apr 2010, 08:49 AM
I have exactly the same problem. I can't even hide the AxisX. At least an workaround to hide it?

Thanks!
0
Giuseppe
Telerik team
answered on 16 Apr 2010, 12:51 PM
Hello Emanuel,

As mentioned in our previous reply on this issue, the problem is related to the general handling of DataTemplates in WPF, and is not specific to the chart control.

As a workaround we would suggest you to set the necessary axis properties in code-behind (you will probably need to create a derived ItemsControl class and use its PrepareContainerForItemOverride(...) method to do so).


Kind regards,
Freddie
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Miha Markic
Top achievements
Rank 1
answered on 13 Aug 2010, 01:32 PM
Telerik guys, even if this is fault in WPF you should try to find a workaround or deal with it with MS (IMO). Not being able to use chart in DataTemplate is a serious flaw.
Anyway, one way to workaround it is to create an UserControl and place the chart inside and then use this UserControl within DataTemplate. It requires some coding though and it is not flexible at all. Oh well, at least it works.
0
Giuseppe
Telerik team
answered on 25 Aug 2010, 04:24 PM
Hi there,

Thank you for contacting us.

Our developers investigated the matter thoroughly once again and were able to find a solution for the .NET4 (WPF4) version of the chart control (the fix will be incorporated immediately and will be available with the weekly internal build on Friday). As for projects that refer the .NET3.5 version of RadChart -- unfortunately for the time being you will need to either use the workaround with the UserControl, or upgrade the project to .NET4 (and RadChart .NET4 binaries).


Regards,
Freddie
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
StackOverflowed
Top achievements
Rank 1
answered on 11 Nov 2010, 03:40 PM
As illustrated in the sample provided by Telerik, the problem it seems is that when a DP is set in the constructor of a Control, and is also set in XAML, and is in a DataTemplate, the XAML setter will be ignored (presumably because the property is already set?). In any case, a solution that I found which I feel is better than wrapping in a UserControl is to subclass RadChart and add a DependencyProperty, which when changed, sets DefaultView. Just use this property instead when setting the DefaultView, and all works fine (and is more succinct):

public class CustomChart : RadChart
{
    public static readonly DependencyProperty DefaultViewShimProperty =
        DependencyProperty.Register("DefaultViewShim", typeof (ChartDefaultView),typeof (CustomChart),new FrameworkPropertyMetadata(null, OnDefaultViewShimPropertyChanged));
  
    private static void OnDefaultViewShimPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        var chart = d as RadChart;
        if (chart == null)
            return;
  
        chart.DefaultView = args.NewValue as ChartDefaultView;
    }
  
    public ChartDefaultView DefaultViewShim
    {
        get { return (ChartDefaultView) GetValue(DefaultViewShimProperty); }
        set { SetValue(DefaultViewShimProperty, value); }
    }
}


EDIT: Nope, doesn't work completely. Had me fooled there for a bit because I was only testing setting
ChartTitle, which does work, but doesn't work for things like setting properties off of the X-axis. 

EDIT2: After some in-depth investigation, the real problem here is DependencyProperty precedence. The RadChart as well as the ChartViewcontrol set certain properties in their constructor, which preclude having them set in a DataTemplate (because the precedence inside of a DataTemplate is ParentTemplate, which is obviously less than the local precedence which has been established on these properties being set in the constructor). I don't see why this is something you've been able to fix in WPF4 but not WPF3. Looking at the default WPF controls, as well as controls supplied by other vendors, and even other Telerik controls (like the RadGridView), shows that nothing is usually set in the constructor of a control, precisely for this reason. I don't understand why, and I frankly find it negligent that the RadChart chooses to ignore this very simple and important rule, and I fail to see why this is only able of being fixed in the WPF4 release.


0
Andy
Top achievements
Rank 1
answered on 22 Dec 2010, 04:31 PM

0
StackOverflowed
Top achievements
Rank 1
answered on 22 Dec 2010, 04:32 PM
(Since edits are not tracked, made this a new post)

After some in-depth investigation, the real problem here is DependencyProperty precedence. The RadChart as well as the ChartViewcontrol set certain properties in their constructor, which preclude having them set in a DataTemplate (because the precedence inside of a DataTemplate is ParentTemplate, which is obviously less than the local precedence which has been established on these properties being set in the constructor). I don't see why this is something you've been able to fix in WPF4 but not WPF3. Looking at the default WPF controls, as well as controls supplied by other vendors, and even other Telerik controls (like the RadGridView), shows that nothing is usually set in the constructor of a control, precisely for this reason. I don't understand why, and I frankly find it negligent that the RadChart chooses to ignore this very simple and important rule, and I fail to see why this is only able of being fixed in the WPF4 release. 
0
Giuseppe
Telerik team
answered on 23 Dec 2010, 02:00 PM
Hi David,

Generally you are correct -- it is best to initialize the default value of a DependencyProperty as part of the static declaration instead of setting it in the constructor. Unfortunately this is applicable only for value type dependency properties as the default value of a DependencyProperty would be shared by all instances of the class that registers it (you can find more information here).

The reason why this is fixed only in WPF4 is the fact that the DependencyObject.SetCurrentValue(...) method that can be used to solve the problem is available only in WPF4:

<Quote>
This method is used by a component that programmatically sets the value of one of its own properties without disabling an application's declared use of the property. The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.
</Quote>


Kind regards,
Freddie
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
StackOverflowed
Top achievements
Rank 1
answered on 28 Dec 2010, 05:05 PM
I understand the issue, and I've run into this problem before myself (DependencyProperty.Register should really take a delegate and not a value). However, this is all predicated on the assumption that these values need to be set in the constructor, or they won't be set at all. Why not set them in the default Style?

If they were set in the default Style, for example, then Style triggers and template triggers would work when they needed to override values, because Style/Template triggers have a higher precedence than Style setters. Sure this would mean that if someone overrode the default Style they'd have to copy some init XAML over, but this has become such common practice in WPF, especially with respect to third party controls. Your own documentation is full of those types of instructions, e.g. going to blend and copying a control template/style, etc

Just a thought.
0
Giuseppe
Telerik team
answered on 03 Jan 2011, 02:19 PM
Hello David,

Thanks for the feedback.

We will forward your suggestion to our developers so they can consider whether it is a feasible solution for all required scenarios for RadChart.


All the best,
Freddie
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
Tags
Chart
Asked by
AdaDog
Top achievements
Rank 1
Answers by
Giuseppe
Telerik team
emi
Top achievements
Rank 1
Miha Markic
Top achievements
Rank 1
StackOverflowed
Top achievements
Rank 1
Andy
Top achievements
Rank 1
Share this question
or