views:

689

answers:

2

I have a chart in a user control. As I want to use multiple charts in the app, I need to set stuff like title of a series for each instance of the user control. It works fine so far, but I'm not able to bind a variable (e.g. seriesTitle) to a target in the user controls xaml.

Please see following code:

Using the user control in MainPage.xaml like that:

<local:ColumnInputChart 
  Name="Chart1" 
  seriesTitle="Diuretics"
  seriesItemId="1"
  getServiceUrl="/Service/MedIntake/1"
  postServiceUrl="/Service/MedIntake/"
  />

Where e.g. seriesTitle is a public var in the user control.

public partial class ColumnInputChart : UserControl
{
    public String seriesItemId { get; set; }
    public String getServiceUrl { get; set; }
    public String postServiceUrl { get; set; }
    public String seriesTitle { get; set; }

In ColumnInputChart.xaml I'm trying to bind seriesTitle to the Title of a series, which does not work. Legend has an empty title. Do I need to set the title programmatically?

<chartingToolkit:AreaSeries ItemsSource="{Binding}" 
   DependentValuePath="Dpd"
   IndependentValuePath="Date" 
   Title="{Binding seriesTitle, Mode=TwoWay}" />

I also realized, that my user control's custom public vars which are set in MainPage.xaml are not yet set during construction of the user control. But they are available once the Page_Loaded Event is fired.

Please see code and comments in code to clarify what I mean:

    public String seriesItemId { get; set; }
    public String getServiceUrl { get; set; }
    public String postServiceUrl { get; set; }
    public String seriesTitle { get; set; }

    public ColumnInputChart()
    {
        // seriesItemId and so on are null here.

        InitializeComponent();
        Loaded += new  RoutedEventHandler(Page_Loaded);

        // and null here.
    }

    void Page_Loaded(object sender, RoutedEventArgs e) {

        // seriesItemId, seriesTitle ... have now the 
        // value form MainPage.xaml
    }

That's my user control's chart code:

    <chartingToolkit:Chart Height="160" x:Name="Chart" BorderThickness="0" Style="{StaticResource MyChartStyle}">
        <chartingToolkit:Chart.Axes>
            <chartingToolkit:DateTimeAxis Orientation="X">
                <chartingToolkit:DateTimeAxis.AxisLabelStyle>
                    <Style TargetType="chartingToolkit:DateTimeAxisLabel">
                        <Setter Property="StringFormat" Value="{}{0:d/M/yyyy}"/>
                    </Style>
                </chartingToolkit:DateTimeAxis.AxisLabelStyle>
            </chartingToolkit:DateTimeAxis>
            <chartingToolkit:LinearAxis Orientation="Y" Location="Left" Title="Intake per day" ShowGridLines="True" />
        </chartingToolkit:Chart.Axes>
        <chartingToolkit:AreaSeries x:Name="MySeries2" ItemsSource="{Binding}" 
            DependentValuePath="Dpd"
            IndependentValuePath="Date" Title="{Binding seriesTitle, Mode=TwoWay}" />
        <chartingToolkit:ColumnSeries ItemsSource="{Binding}"
           DependentValuePath="Dpd"
           IndependentValuePath="Date" 
           IsSelectionEnabled="True" 
           Title="Missing Values"
           SelectionChanged="ColumnSeries_SelectionChanged" />
    </chartingToolkit:Chart>

And I'm using ObservableCollections as ItemSource for the chart.

        medIntakes = new ObservableCollection<MedIntakeObj>();
        medIntakeBars = new ObservableCollection<MedIntakeObj>();

        ((AreaSeries)Chart.Series[0]).ItemsSource = medIntakes;
        ((ColumnSeries)Chart.Series[1]).ItemsSource = medIntakeBars;

Thanks for any help!

A: 

This works for me ;-)

But I'm still looking for better solutions.

void Page_Loaded(object sender, RoutedEventArgs e) {

    // seriesItemId, seriesTitle ... have now the 
    // value form MainPage.xaml

    ((AreaSeries)Chart.Series[0]).Title = seriesTitle;
}
andreas
But you really shouldn't have to settle for this.
AnthonyWJones
This is definitely not very elegant... Any better ideas?
andreas
A: 

Anthony's comments helped me quite a bit. I created a ViewModel for my UserControl.

public class ChartViewModel
{
    public String seriesTitle { get; set; }
    public String axisTitle { get; set; }

    public int seriesId { get; set; }
    public String serviceUrl { get; set; }

    public String comboText { get; set; }
    public List<String> comboList { get; set; }

Assigning ViewModel to DataContext

public ColumnInputChart(ChartViewModel vm, SimpleCallback cb)
{
    InitializeComponent();

    this.vm = vm;
    this.cbStartScroll = cb;
    this.Chart.DataContext = vm;

The xaml of the UserControl is just a little different now and binding works

        < ... />
        <chartingToolkit:LinearAxis Orientation="Y" Location="Left" Title="{Binding axisTitle}" 
                                    ShowGridLines="True" Interval="1" />
    </chartingToolkit:Chart.Axes>
    <chartingToolkit:AreaSeries ItemsSource="{Binding values}" 
        DependentValuePath="Dpd"
        IndependentValuePath="Date"
        Title="{Binding seriesTitle}" />
    <chartingToolkit:ColumnSeries ItemsSource="{Binding bars}"
       DependentValuePath="Dpd"
       IndependentValuePath="Date" 
       IsSelectionEnabled="True" 
       Title="Missing Values"
       SelectionChanged="ColumnSeries_SelectionChanged" />
</chartingToolkit:Chart>

Now I wonder whether it is a good design decision to integrate the ObservableCollections into to ViewModel or not. I can assign them the ItemSource anyway and they are very much related to the UserControl so I guess keeping them in the UserControl is an okay choice. Please feel free to comment on that.

andreas