2016-05-11 11 views
5

Ich muss eine PieChart anzeigen, ich verwende derzeit Modern UI (Metro) Charts. Ich habe den Code in der Dokumentation kopiert und das Problem ist, dass ich immer den Rand und den Titel auf dem Bildschirm habe, aber kein Diagramm.PieChart zeigt nicht

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

Antwort

1

erstellen ViewModel Daten für das Diagramm zu halten, und weisen Sie auf Ihre DataContext wie unten dargestellt:

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> 

Ansichtsmodell:

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: Anstatt Ihre mit ViewModel in XAML erstellt wie bisher, können Sie es auch dynamisch wie folgt:

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

Der Grund, warum dies funktioniert, ist, weil Sie den 'DataContext' des' UserControl' einstellen. Dies ist das Stück, das im Code des ursprünglichen Posters fehlt. – Cameron

+0

Dies ist Standard 'MVVM'. – jsanalytics

+0

Das ist richtig. Sie können aber auch den DataContext eines Steuerelements an sich selbst binden, was das ursprüngliche Poster versucht. Sie haben Code angegeben, der funktioniert, aber nicht explizit gesagt hat, was die Antwort auf das Problem des ursprünglichen Posters ist. :) – Cameron

0

Ich bin kein Experte mit der Kontrolle, aber ich vermute, dass Ihre ItemsSource Bindung schlägt fehl. Die Errors Sammlung ist auf dem Benutzer-Steuerelement als eine Eigenschaft und Ihre Bindung an die ItemsSource wird standardmäßig von der DataContext gehen, die ich denke, ist Null in Ihrem Fall. die die Kontrolle zu bekommen direkt über eine Bindung Sie wahrscheinlich es, indem Sie so etwas wie (unter der Annahme, dass Sie „local“ auf den Namespace Karte wo Ad_Aj befindet) mit der RelativeSource Markup Erweiterung arbeiten würden:

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

I Denken Sie jedoch, dass Sie Ihre Errors Informationen in einem Ansichtsmodell setzen und dann auf den Datenkontext setzen und die Bindungen so verwenden möchten, wie Sie sie haben, da die Errors Informationen wirklich Daten und getrennt von der Benutzeroberfläche sind.

1

Sie sind also auf dem richtigen Weg! Ihnen fehlt nur eine Codezeile!

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 }); 
    } 
} 

Dies ist MVVM, aber es ist nicht wahr MVVM. True MVVM hat eine separate ViewModel-Klasse.Was Sie hier tun, ist die Verwendung des Code-Behinds Ihrer View als ViewModel. Es funktioniert, und niemand wird dich deswegen bekämpfen. Wenn Sie jedoch versuchen, eine echte MVVM zu erstellen, müssen Sie Ihre Klassen trennen.

jstreet has a great answer/example wie Sie Ihren DataContext (aka die "Bindung") auf das ViewModel in XAML setzen.

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

jedoch zur Kenntnis nehmen, dass er eine separate ViewModel Klasse verwenden. Der Code, den du in deiner Frage angegeben hast, tut das nicht tue dies, also bin ich nicht sicher, wie man es auf die gleiche Weise macht. Es ist auch erwähnenswert, dass, wenn Ihre ViewModel Klasse Konstruktor Abhängigkeitsinjektion verwendet oder Parameter hat, dass Sie einige Magie verwenden müssen, um dies zum Funktionieren zu bringen. Wenn das der Fall ist, ist es einfacher, es einfach im Konstruktor zu setzen.