2016-05-11 44 views
5

Devo visualizzare un PieChart, Attualmente sto usando Modern UI (Metro) Charts. Ho copiato il codice nella documentazione e il problema è che ho sempre il bordo e il titolo sullo schermo ma nessun grafico.PieChart non viene visualizzato

XAML

<UserControl x:Class="Projet.Recources0.Statistique.Ad_Aj" 
     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:mui="http://firstfloorsoftware.com/ModernUI" 
     xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" 
     xmlns:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart" 
     mc:Ignorable="d" d:DesignWidth="1000" Height="670"> 

<UserControl.Resources> 
    <Style x:Key="MinimalChartStyle" TargetType="{x:Type chart:ChartBase}"> 
     <Setter Property="Width" Value="500"/> 
     <Setter Property="Height" Value="500"/>    
    </Style> 
</UserControl.Resources> 
<Grid > 
    <chart:PieChart 
    Style="{StaticResource MinimalChartStyle}" 
    ChartTitle="Minimal Pie Chart" 
    ChartSubTitle="Chart with fixed width and height" 
    SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" > 
     <chart:PieChart.Series> 
      <chart:ChartSeries 
      SeriesTitle="Errors" 
      DisplayMember="Category" 
      ValueMember="Number" 
      ItemsSource="{Binding Path=Errors}" /> 
     </chart:PieChart.Series> 
    </chart:PieChart> 
</Grid> 

CS

using MySql.Data.MySqlClient; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Configuration; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace Projet.Recources0.Statistique 
{ 
    /// <summary> 
    /// Interaction logic for Ad_Aj.xaml 
    /// </summary> 

    public partial class Ad_Aj : UserControl 
    { 
     public ObservableCollection<TestClass> Errors { get; private set; } 

     public Ad_Aj() 
     { 
      Errors = new ObservableCollection<TestClass>(); 
      Errors.Add(new TestClass() { Category = "Globalization", Number = 75 }); 
      Errors.Add(new TestClass() { Category = "Features", Number = 2 }); 
      Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 }); 
      Errors.Add(new TestClass() { Category = "Correctness", Number = 83}); 
      Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 }); 
     } 

     private object selectedItem = null; 
     public object SelectedItem 
     { 
      get 
      { 
       return selectedItem; 
      } 
      set 
      { 
       // selected item has changed 
       selectedItem = value;     
      } 
     } 
    } 

    // class which represent a data point in the chart 
    public class TestClass 
    { 
     public string Category { get; set; } 

     public int Number { get; set; } 
    } 
} 

Pie Chart

risposta

1

Creare un ViewModel per contenere i dati per il grafico e assegnarlo al vostro DataContext come illustrato di seguito:

XAML:

<Window x:Class="WpfApplication222.Window2" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart" 
    xmlns:local="clr-namespace:WpfApplication222" 
    mc:Ignorable="d" 
    Title="Window2" Height="350" Width="525"> 

<Window.DataContext> 
    <local:PieChartViewModel/> 
</Window.DataContext> 

<Grid> 
    <chart:PieChart 
     ChartTitle="Minimal Pie Chart" 
     ChartSubTitle="Chart with fixed width and height" 
     SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" > 
     <chart:PieChart.Series> 
      <chart:ChartSeries 
       SeriesTitle="Errors" 
       DisplayMember="Category" 
       ValueMember="Number" 
       ItemsSource="{Binding Path=Errors}" /> 
     </chart:PieChart.Series> 
    </chart:PieChart> 
</Grid> 

ViewModel:

public class PieChartViewModel 
{ 
    public ObservableCollection<TestClass> Errors { get; private set; } 

    public PieChartViewModel() 
    { 
     Errors = new ObservableCollection<TestClass>(); 
     Errors.Add(new TestClass() { Category = "Globalization", Number = 75 }); 
     Errors.Add(new TestClass() { Category = "Features", Number = 2 }); 
     Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 }); 
     Errors.Add(new TestClass() { Category = "Correctness", Number = 83 }); 
     Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 }); 
    } 
} 

enter image description here

EDIT: Invece di avere il vostro ViewModel creato in XAML come prima, si può anche fare in modo dinamico nel seguente modo:

XAML:

Window x:Class="WpfApplication222.Window2" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart" 
    xmlns:local="clr-namespace:WpfApplication222" 
    mc:Ignorable="d" 
    Title="Window2" Height="350" Width="525" Loaded="Window_Loaded"> 

<Grid> 
    <chart:PieChart 
     ChartTitle="Minimal Pie Chart" 
     ChartSubTitle="Chart with fixed width and height" 
     SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" > 
     <chart:PieChart.Series> 
      <chart:ChartSeries 
       SeriesTitle="Errors" 
       DisplayMember="Category" 
       ValueMember="Number" 
       ItemsSource="{Binding Path=Errors}" /> 
     </chart:PieChart.Series> 
    </chart:PieChart> 
</Grid> 

CS:

public partial class Window2 : Window 
{ 
    PieChartViewModel viewModel; 

    public Window2() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     viewModel = new PieChartViewModel(); 

     viewModel.Errors.Add(new TestClass() { Category = "Globalization", Number = 75 }); 
     viewModel.Errors.Add(new TestClass() { Category = "Features", Number = 2 }); 
     viewModel.Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 }); 
     viewModel.Errors.Add(new TestClass() { Category = "Correctness", Number = 83 }); 
     viewModel.Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 }); 

     DataContext = viewModel; 
    } 
} 

ViewModel:

public class PieChartViewModel 
{ 
    public ObservableCollection<TestClass> Errors { get; private set; } 

    public PieChartViewModel() 
    { 
     Errors = new ObservableCollection<TestClass>(); 
    } 
} 
+0

Il motivo per cui questo funziona è perché si sta impostando il 'DataContext' di' UserControl'. Questo è il pezzo che manca nel codice del poster originale. – Cameron

+0

Questo è lo standard 'MVVM'. – jsanalytics

+0

Questo è corretto. Ma puoi anche associare DataContext di un controllo a se stesso, che è ciò che il poster originale sta tentando di fare. Hai dato il codice che funziona, ma non hai detto esplicitamente quale sia la risposta al problema del poster originale. :) – Cameron

0

Io non sono un esperto con il controllo, ma sto indovinando che l'associazione ItemsSource non funziona. La collezione Errors si trova sul controllo utente come una proprietà e l'associazione per lo ItemsSource è impostata per impostazione predefinita su DataContext che, a mio avviso, è nullo nel tuo caso. Per ottenere il controllo direttamente attraverso un legame si sarebbe probabilmente a farlo funzionare con l'estensione RelativeSource di markup facendo qualcosa di simile (supponendo che si mappare "locale" per lo spazio dei nomi in cui si trova Ad_Aj):

ItemsSource = "{Binding RelativeSource={RelativeSource AncestorType=local:Ad_Aj, Mode=FindAncestor}, Path=Errors}" 

I pensa però che vorresti inserire le tue informazioni Errors in un modello di visualizzazione e poi impostarle nel contesto dati e utilizzare le associazioni come le hai, dal momento che le informazioni Errors sono realmente dati e separate dall'interfaccia utente.

1

Quindi sei sulla strada giusta! Ti manca solo una riga di codice!

public partial class Ad_Aj : UserControl 
{ 
    public ObservableCollection<TestClass> Errors { get; private set; } 

    public Ad_Aj() 
    { 
     /* 
     * ---------------------------- 
     * This is line you're missing. 
     * ---------------------------- 
     */ 
     DataContext = this; 
     /* 
     * ---------------------------- 
     */ 
     Errors = new ObservableCollection<TestClass>(); 
     Errors.Add(new TestClass() { Category = "Globalization", Number = 75 }); 
     Errors.Add(new TestClass() { Category = "Features", Number = 2 }); 
     Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 }); 
     Errors.Add(new TestClass() { Category = "Correctness", Number = 83}); 
     Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 }); 
    } 
} 

Questo è MVVM, ma non è vero MVVM. True MVVM ha una classe ViewModel separata.Quello che stai facendo qui è usare il codice dietro la tua vista come ViewModel. Funziona, e nessuno ti combatterà su questo. Tuttavia, se stai cercando di fare MVVM vero, dovrai separare le tue classi.

jstreet has a great answer/example di come impostare DataContext (ovvero "associazione") a ViewModel in XAML.

<Window.DataContext> 
    <local:PieChartViewModel /> 
</Window.DataContext> 

Tuttavia, prendere atto che sta usando una classe separata ViewModel. Il codice che hai fornito nella tua domanda è non, quindi non sono sicuro di come farlo nello stesso modo. Inoltre, vale la pena ricordare che se la tua classe ViewModel utilizza l'iniezione delle dipendenze del costruttore o ha parametri, dovrai usare un po 'di magia per far funzionare tutto questo. In tal caso, è più semplice impostarlo nel costruttore.

Problemi correlati