PieChart is not displayed

I need to display PieChart , I am currently using Modern Interface Graphics (Metro) . I copied the code in the documentation, and the problem is that I always have a border and a title on the screen, but no diagram.

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

+5
source share
3 answers

Create a ViewModel to save data for your chart and assign it a DataContext , as shown below:

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: Instead of creating the ViewModel in XAML as before, you can also do it dynamically as follows:

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>(); } } 
+1
source

So, you are on the right track! You are missing one line of code!

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

This is MVVM, but it is not true MVVM. True MVVM has a separate ViewModel class. What you are doing here is using the "Behind Your View" code as a ViewModel. It works and no one will fight you. However, if you are trying to execute true MVVM, you need to separate your classes.

jstreet has an excellent answer / example on how to set a DataContext (otherwise called a binding) in a ViewModel in XAML.

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

However, note that it uses a separate ViewModel class. The code you provided in your question does not , so I'm not sure how to do this. Also, it's worth mentioning that if your ViewModel class uses constructor dependency injection or has parameters, you will have to use some magic to make this work. If so, it's easier to just set it in the constructor.

+1
source

I am not an expert with a control, but I assume that the ItemsSource binding is not being performed. The Errors collection is in the user control as a property, and your binding on the ItemsSource by default be disconnected from the DataContext , which I think is null in your case. To gain control directly through the binding, you will probably get it to work with the RelativeSource markup extension by doing something like this (assuming you map "local" to the namespace where Ad_Aj is located):

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

I think you would like to put your Errors information in a presentation model, and then set it in the data context and use the bindings as you have them, since the Errors information is really data and is separate from the user interface.

0
source

All Articles