2016-05-16 2 views
0

J'ai une classe appelée ShellViewModel et une page WPF appelée Shell.xaml. Dans mon ShellViewModel j'ai une fonction qui lit les données d'un fichier .csv et affiche les données dans la grille de données dans Shell.xaml Les données sont représentées sur un graphique sous forme de tracé de ligne.System.ArgumentException: la propriété 'Value' était déjà enregistrée par 'Point'

Le fichier est lu correctement et les données sont affichées correctement dans le DataGrid. La structure des données a 25 colonnes. La première colonne est le nom des données et les 24 colonnes suivantes sont des points de données. Bien que les données s'affichent correctement dans la grille de données, le graphique ne contient aucun point de données.

Ceci est le code de mon graphique. L'erreur que je reçois est "

System.ArgumentException: propriété 'Value' a déjà été enregistré par 'Point'"

Notes: obsLoadForecasts a les données stockées qui obtient affiché dans la DataGrid

code de ShellViewModel.cs pour le graphique:

public void UpdateLoadChart() 
{ 
    var forecastList = obsLoadForecasts.ToList(); 
    var dataList = new List<ForecastPoint>(); 

    forecastList.Where(a => a.ObsForecast.ZoneName == zoneName).ToList().ForEach(a => 
    { 
     dataList.Add(new ForecastPoint(1, a.ObsForecast.Hr1)); 
     dataList.Add(new ForecastPoint(2, a.ObsForecast.Hr2)); 
     dataList.Add(new ForecastPoint(3, a.ObsForecast.Hr3)); 
     dataList.Add(new ForecastPoint(4, a.ObsForecast.Hr4)); 
     dataList.Add(new ForecastPoint(5, a.ObsForecast.Hr5)); 
     dataList.Add(new ForecastPoint(6, a.ObsForecast.Hr6)); 
     dataList.Add(new ForecastPoint(7, a.ObsForecast.Hr7)); 
     dataList.Add(new ForecastPoint(8, a.ObsForecast.Hr8)); 
     dataList.Add(new ForecastPoint(9, a.ObsForecast.Hr9)); 
     dataList.Add(new ForecastPoint(10, a.ObsForecast.Hr10)); 
     dataList.Add(new ForecastPoint(11, a.ObsForecast.Hr11)); 
     dataList.Add(new ForecastPoint(12, a.ObsForecast.Hr12)); 
     dataList.Add(new ForecastPoint(13, a.ObsForecast.Hr13)); 
     dataList.Add(new ForecastPoint(14, a.ObsForecast.Hr14)); 
     dataList.Add(new ForecastPoint(15, a.ObsForecast.Hr15)); 
     dataList.Add(new ForecastPoint(16, a.ObsForecast.Hr16)); 
     dataList.Add(new ForecastPoint(17, a.ObsForecast.Hr17)); 
     dataList.Add(new ForecastPoint(18, a.ObsForecast.Hr18)); 
     dataList.Add(new ForecastPoint(19, a.ObsForecast.Hr19)); 
     dataList.Add(new ForecastPoint(20, a.ObsForecast.Hr20)); 
     dataList.Add(new ForecastPoint(21, a.ObsForecast.Hr21)); 
     dataList.Add(new ForecastPoint(22, a.ObsForecast.Hr22)); 
     dataList.Add(new ForecastPoint(23, a.ObsForecast.Hr23)); 
     dataList.Add(new ForecastPoint(24, a.ObsForecast.Hr24)); 
    }); 

    ObsLoadChartData = dataList; 
    RaisePropertyChanged("ObsLoadChartData"); 

    if (!(obsLoadForecasts.Exists(a => a.ObsForecast.ZoneName.Contains("Interchange")))) 
    { 
     try 
     { 
      //Peak Load Forecast values defined 
      maxRTOvalue = dataList.Max(ForecastPoint => ForecastPoint.Value); 
      maxRTOhour = dataList.FindIndex(ForecastPoint => ForecastPoint.Value == maxRTOvalue); 
      maxRTOhour = maxRTOhour + 1; 
     } 
     catch 
     { 
      Log("Unable to determine Peak Load Forecast "); 

      maxRTOvalue = 0; 
      maxRTOhour = 0; 
      maxRTOhour = 0; 
     } 
    } 
} 

public class ForecastPoint : DependencyObject 
{ 
    public ForecastPoint(int hour, decimal value) 
    { 
     Hour = hour; 
     Value = value; 
    } 

    public static readonly DependencyProperty _hour = DependencyProperty.Register("Hour", typeof(Int32), typeof(ForecastPoint)); 
    public Int32 Hour 
    { 
     get { return (int)GetValue(_hour); } 
     set { SetValue(_hour, value); } 
    } 

    public static readonly DependencyProperty _value = DependencyProperty.Register("Value", typeof(decimal), typeof(Point)); 
    public decimal Value 
    { 
     get { return (decimal)GetValue(_value); } 
     set { SetValue(_value, value); } 
    } 
} 

code dans Shell.x aml:

<me:LoadChart x:Name="MyLoadChart" SnapsToDevicePixels="True" /> 

code dans mon LoadChart.xaml:

<UserControl x:Class="ProbeCTO.LoadChart" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" 
     xmlns:chartingPrimitives="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit" 
     xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit" 
     xmlns:me="clr-namespace:ProbeCTO" 
     mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> 
<UserControl.Resources> 
    <Style TargetType="{x:Type charting:Chart}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type charting:Chart}"> 
        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> 
         <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition Height="*" /> 
          </Grid.RowDefinitions> 

          <datavis:Title Content="{TemplateBinding Title}" HorizontalAlignment="Left" Margin="20 0" FontWeight="Bold" Foreground="{StaticResource DefaultButtonBrush}" Style="{TemplateBinding TitleStyle}" /> 

          <!-- Use a nested Grid to avoid possible clipping behavior resulting from ColumnSpan+Width=Auto --> 
          <Grid Grid.Row="1" Margin="0,15,0,15"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="Auto" /> 
           </Grid.ColumnDefinitions> 

           <chartingPrimitives:EdgePanel x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}"> 
            <Grid Canvas.ZIndex="-1" Style="{TemplateBinding PlotAreaStyle}" /> 
            <Border Canvas.ZIndex="10" BorderBrush="#FF919191" BorderThickness="1 0 0 1" /> 
           </chartingPrimitives:EdgePanel> 
          </Grid> 
         </Grid> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 
<Grid> 
    <charting:Chart x:Name="MyChart" Title="{Binding ObsSelectedLoadForecast.ObsForecast.ZoneName, TargetNullValue=RTO, FallbackValue=RTO}" Grid.Row="1" SnapsToDevicePixels="True" Foreground="#DDD" BorderThickness="0"> 
     <charting:Chart.PlotAreaStyle> 
      <Style TargetType="{x:Type Grid}"> 
       <Setter Property="Background" Value="{x:Null}" /> 
      </Style> 
     </charting:Chart.PlotAreaStyle> 
     <charting:Chart.Axes> 
      <charting:LinearAxis Orientation="X" ShowGridLines="False" Interval="1" /> 
      <charting:LinearAxis Orientation="Y" ShowGridLines="False" /> 
     </charting:Chart.Axes> 
     <charting:Chart.Series> 
      <charting:AreaSeries ItemsSource="{Binding ObsLoadChartData}" 
             IndependentValuePath="Hour" 
             DependentValuePath="Value"> 
      </charting:AreaSeries> 
      <charting:LineSeries ItemsSource="{Binding ObsLoadChartData}" 
             IndependentValuePath="Hour" 
             DependentValuePath="Value"> 
      </charting:LineSeries> 
     </charting:Chart.Series> 
    </charting:Chart> 
</Grid> 

Répondre

1

Facile: Vous avez passé un mauvais argument DependencyProperty.Register. Je le fais deux fois par semaine grâce au copier-coller.

public static readonly DependencyProperty _value = 
    DependencyProperty.Register("Value", 
     typeof(decimal), 
     typeof(ForecastPoint)); 

Le dernier argument était typeof(Point) dans votre extrait, mais il doit être typeof(ForecastPoint) - le type de la classe en déclarant, comme il est quelques lignes ci-dessus là où vous enregistrez la propriété Hour. Par ailleurs, je nommerais ces ValueProperty et HourProperty au lieu de _value et _hour. C'est la convention, et c'est ce que les gens attendent de voir. Toute personne essayant d'appeler obj.SetValue(ForecastPoint.ValueProperty, value) sera dans une frustration inutile.

+0

Merci beaucoup – someone

+0

@someone Si cette réponse a résolu votre problème, vous devriez le marquer comme la bonne réponse. –