Hi all
I am trying to add Series binding to the Visifire graphing controls set. To this end i have created a SeriesSource dependency property of time DataSeriesCollection
. This is bound in the front end using:
`<Chart SeriesSource={Binding Series} />`
Problem
When the source changes, the validation callback is called. The value that is passed to this is the correct value, a populated ObservableCollection<something>
. Immediately after the validate value is called, the CoerceValue callback is called by something, and the value that is sent to it is an EMPTY ObservableCollection<something>
. Bounty will go to anyone who can:
- Get the correct populated
ObservableCollection<someting>
passed to the CoerceValue callback OR - Get the correct value being passed to the OnSeriesSourceChanged callback OR
- Explain to me how i can do any of the above :)
Here is the data template for the view:
<DataTemplate DataType="{x:Type vm:ReportViewModel}">
<Grid Name="rootGrid">
<visifire:Chart Grid.Row="1" SeriesSource="{Binding Series}">
<visifire:Chart.AxesX>
<visifire:Axis Title="X axis" />
</visifire:Chart.AxesX>
<visifire:Chart.AxesY>
<visifire:Axis Title="Y axis" />
</visifire:Chart.AxesY>
</visifire:Chart>
</Grid>
</DataTemplate>
Here is the target Dependency Property
//Getter and setter for Dependency Property
public ObservableCollection<DataSeries> SeriesSource
{
get { return (ObservableCollection<DataSeries>)GetValue(SeriesSourceProperty); }
set { SetValue(SeriesSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for SeriesSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SeriesSourceProperty =
DependencyProperty.Register("SeriesSource", typeof(ObservableCollection<DataSeries>), typeof(Chart), new UIPropertyMetadata(new ObservableCollection<DataSeries>(), new PropertyChangedCallback(OnSeriesSourceChange), new CoerceValueCallback(CoerceSeries)), new ValidateValueCallback(ValidateSeriesSource));
//Value validation callback
private static bool ValidateSeriesSource(object value)
{
if (value as ObservableCollection<DataSeries> != null)
return true;
return false;
}
//Dependency Property Changed callback
private static void OnSeriesSourceChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Chart c = d as Chart;
if (c == null)
return;
//This line was causing the issue. It was overriding the setter
c.SeriesSource = (DataSeriesCollection)e.NewValue;
}
//Coerce Value callback
private static object CoerceSeries(DependencyObject d, object value)
{
Chart c = d as Chart;
var collection = value as System.Collections.ObjectModel.ObservableCollection<Visifire.Charts.DataSeries>;
foreach (var item in c.Series)
{
if (!collection.Contains(item))
c.Series.Remove(item);
}
foreach (var item in collection)
{
if (!c.Series.Contains(item))
c.Series.Add(item);
}
return collection;
}
New information
The value being received by the CoerceValue callback is ALWAYS the first value which that property was set to. So if the first value i pass it is a list with 1 item, it will always coerce the value back to a list with one item!
Edit: found the issue, it was in the property changed callback. Credit goes to Matt for helping me out with the CoerceValue callback