J'essaie d'ajouter une liaison série à l'ensemble de contrôles graphiques Visifire. À cette fin, j'ai créé une propriété de dépendance SeriesSource de l'heure DataSeriesCollection
. Ceci est lié à l'extrémité avant à l'aide:La liaison WPF ne s'applique pas à la cible après l'initialisation
`<Chart SeriesSource={Binding Series} />`
Problème
Lorsque la source change, le rappel de validation est appelée. La valeur qui est passée à ceci est la valeur correcte, une ObservableCollection<something>
remplie. Immédiatement après l'appel de la valeur de validation, le rappel CoerceValue est appelé par quelque chose, et la valeur qui lui est envoyée est ObservableCollection<something>
. Bounty ira à tous ceux qui peuvent:
- Obtenez le bon peuplé
ObservableCollection<someting>
passé au rappel CoerceValue OU - obtenir la valeur correcte étant passé à la fonction de rappel OnSeriesSourceChanged OU
- Expliquez-moi comment je peux faire tout de ce qui précède :)
Voici le modèle de données pour la vue:
<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>
Voici la cible de propriété de dépendance
//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;
}
De nouvelles informations
La valeur reçue par le rappel de CoerceValue est toujours la première valeur que la propriété a été définie sur. Donc si la première valeur que je passe est une liste avec 1 item, elle forcera toujours la valeur à revenir à une liste avec un item!
Modifier: a trouvé le problème, il était dans la propriété a changé callback. Crédit à Matt pour m'avoir aidé avec le rappel CoerceValue
Juste pour confirmer: Vous vérifiez si la valeur est définie à l'aide d'un point d'arrêt sur le setter de la propriété de dépendance SeriesSource du graphique. Cela ne fonctionnera pas - les getters et les setters sur les points de données liés aux données sont ignorés. –
Voir le code ci-dessus. Im en utilisant des points d'arrêt sur la fonction OnSeriesChange – TerrorAustralis
Parfois, ces choses ne font que se réparer! :) Désolé je ne pourrais pas être plus d'aide, mais au moins je vous ai aidé à vous aider je suppose. –