To implement a selection in the MVVM style, enable the selection feature using the ChartControl.SelectionMode property. Set this property to a value different from None.
Then, use the ChartControl.SelectedItem property to set or get a single selected view model object, or the ChartControl.SelectedItems property to set or get several view model objects.
<Window xmlns:dxm="http://schemas.devexpress.com/winfx/2008/xaml/map"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
Title="MainWindow" Height="720" Width="1280"
x:Class="MVVM_Selection.MainWindow"
dx:ThemeManager.Theme="Office2013">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<dxc:ChartControl Grid.Column="0"
Margin="4,4,2,4"
SelectionMode="Single"
SelectedItem="{Binding Path=SelectedCountry, Mode=TwoWay}">
<dxc:ChartControl.Palette>
<dxc:Office2013Palette/>
</dxc:ChartControl.Palette>
<dxc:ChartControl.Titles>
<dxc:Title Content="Top 10 Countries By Area"
HorizontalAlignment="Center"/>
</dxc:ChartControl.Titles>
<dxc:ChartControl.Legend>
<dxc:Legend HorizontalPosition="LeftOutside"
VerticalPosition="Top"
Orientation="Vertical" IndentFromDiagram="2"/>
</dxc:ChartControl.Legend>
<dxc:SimpleDiagram2D>
<dxc:PieSeries2D DataSource="{Binding Path=CountriesData}"
ArgumentDataMember="Name"
ValueDataMember="Area"
LegendTextPattern="{}{A}">
<dxc:PieSeries2D.Model>
<dxc:BorderlessFlatPie2DModel/>
</dxc:PieSeries2D.Model>
</dxc:PieSeries2D>
</dxc:SimpleDiagram2D>
</dxc:ChartControl>
<dxc:ChartControl Grid.Column="1"
Margin="2,4,4,4">
<dxc:ChartControl.Palette>
<dxc:Office2013Palette/>
</dxc:ChartControl.Palette>
<dxc:ChartControl.Titles>
<dxc:Title Content="{Binding Path=SelectedCountry.Name, Mode=OneWay}"
HorizontalAlignment="Center"/>
</dxc:ChartControl.Titles>
<dxc:XYDiagram2D>
<dxc:XYDiagram2D.AxisX>
<dxc:AxisX2D>
<dxc:AxisX2D.WholeRange>
<dxc:Range AutoSideMargins="False" SideMarginsValue="0"/>
</dxc:AxisX2D.WholeRange>
</dxc:AxisX2D>
</dxc:XYDiagram2D.AxisX>
<dxc:XYDiagram2D.AxisY>
<dxc:AxisY2D>
<dxc:AxisY2D.WholeRange>
<dxc:Range dxc:AxisY2D.AlwaysShowZeroLevel="False"/>
</dxc:AxisY2D.WholeRange>
<dxc:AxisY2D.Title>
<dxc:AxisTitle Content="Population, millons"/>
</dxc:AxisY2D.Title>
</dxc:AxisY2D>
</dxc:XYDiagram2D.AxisY>
<dxc:AreaSeries2D DataSource="{Binding Path=SelectedCountry.PopulationDynamics}"
ArgumentDataMember="Year"
ValueDataMember="Population"/>
</dxc:XYDiagram2D>
</dxc:ChartControl>
</Grid>
</Window>
Imports MVVM_Selection.Model
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Globalization
Imports System.Xml.Linq
Namespace MVVM_Selection.ViewModel
Public Class DashboardViewModel
Implements INotifyPropertyChanged
Private Shared instance_Renamed As DashboardViewModel
Private ReadOnly countriesData_Renamed As List(Of CountryStatisticInfo)
Private selectedCountry_Renamed As CountryStatisticInfo
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Shared ReadOnly Property Instance() As DashboardViewModel
Get
If instance_Renamed Is Nothing Then
instance_Renamed = New DashboardViewModel()
End If
Return instance_Renamed
End Get
End Property
Public ReadOnly Property CountriesData() As List(Of CountryStatisticInfo)
Get
Return countriesData_Renamed
End Get
End Property
Public Property SelectedCountry() As CountryStatisticInfo
Get
Return selectedCountry_Renamed
End Get
Set(ByVal value As CountryStatisticInfo)
If selectedCountry_Renamed IsNot value Then
selectedCountry_Renamed = value
OnPropertyChanged("SelectedCountry")
End If
End Set
End Property
Public Sub PopulateData(ByVal filepath As String)
countriesData_Renamed.AddRange(CountriesInfoDataReader.Load(filepath))
selectedCountry_Renamed = countriesData_Renamed(0)
End Sub
Private Sub New()
countriesData_Renamed = New List(Of CountryStatisticInfo)()
End Sub
Private Sub OnPropertyChanged(ByVal propertyName As String)
Dim propertyChangedEventHendler As PropertyChangedEventHandler = PropertyChangedEvent
If propertyChangedEventHendler IsNot Nothing Then
propertyChangedEventHendler(Me, New PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
Friend Class CountriesInfoDataReader
Private Shared Function LoadStatistic(ByVal populationDynamic As XElement) As List(Of PopulationStatisticByYear)
Dim statistic As New List(Of PopulationStatisticByYear)()
For Each populationDynamicItem As XElement In populationDynamic.Elements("PopulationStatisticByYear")
Dim year As Integer = Integer.Parse(populationDynamicItem.Element("Year").Value)
Dim population As Long = Long.Parse(populationDynamicItem.Element("Population").Value)
Dim urbanPercent As Double = Double.Parse(populationDynamicItem.Element("UrbanPercent").Value, CultureInfo.InvariantCulture)
Dim popDynamicItem As New PopulationStatisticByYear(year, CDbl(population) / 1000000.0, urbanPercent)
statistic.Add(popDynamicItem)
Next populationDynamicItem
Return statistic
End Function
Public Shared Function Load(ByVal path As String) As List(Of CountryStatisticInfo)
Dim doc As XDocument = XDocument.Load(path)
Dim data As New List(Of CountryStatisticInfo)()
For Each countryInfo As XElement In doc.Root.Elements("CountryInfo")
Dim name As String = countryInfo.Element("Name").Value
Dim areaSqKm As Double = UInteger.Parse(countryInfo.Element("AreaSqrKilometers").Value)
Dim statistic As List(Of PopulationStatisticByYear) = LoadStatistic(countryInfo.Element("Statistic"))
Dim countryInfoInstance As New CountryStatisticInfo(name, areaSqKm / 1000000, statistic)
data.Add(countryInfoInstance)
Next countryInfo
Return data
End Function
End Class
End Namespace
Imports System.Collections.Generic
Namespace MVVM_Selection.Model
Public Class CountryStatisticInfo
Private ReadOnly name_Renamed As String
Private ReadOnly area_Renamed As Double
Private ReadOnly statistics As List(Of PopulationStatisticByYear)
Public ReadOnly Property Name() As String
Get
Return name_Renamed
End Get
End Property
' Measured in millions of square kilometers.
Public ReadOnly Property Area() As Double
Get
Return area_Renamed
End Get
End Property
Public ReadOnly Property PopulationDynamics() As List(Of PopulationStatisticByYear)
Get
Return statistics
End Get
End Property
Public Sub New(ByVal name As String, ByVal area As Double, ByVal statistics As List(Of PopulationStatisticByYear))
Me.name_Renamed = name
Me.area_Renamed = area
Me.statistics = statistics
End Sub
End Class
Public Class PopulationStatisticByYear
Private year_Renamed As Integer
Private populationMillionsOfPeople As Double
Private urbanPercent_Renamed As Double
Public ReadOnly Property Year() As Integer
Get
Return year_Renamed
End Get
End Property
' Measured in Millions of people.
Public ReadOnly Property Population() As Double
Get
Return populationMillionsOfPeople
End Get
End Property
Public ReadOnly Property UrbanPercent() As Double
Get
Return urbanPercent_Renamed
End Get
End Property
Public ReadOnly Property RuralPercent() As Double
Get
Return 100 - urbanPercent_Renamed
End Get
End Property
Public Sub New(ByVal year As Integer, ByVal populationMillionsOfPeople As Double, ByVal urbanPercent As Double)
Me.year_Renamed = year
Me.populationMillionsOfPeople = populationMillionsOfPeople
Me.urbanPercent_Renamed = urbanPercent
End Sub
End Class
End Namespace
Imports MVVM_Selection.ViewModel
Imports System.Windows
Namespace MVVM_Selection
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
Dim viewModel = DashboardViewModel.Instance
viewModel.PopulateData("..\..\Data\Top10LargestCountriesInfo.xml")
DataContext = viewModel
End Sub
End Class
End Namespace
using MVVM_Selection.Model;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Xml.Linq;
namespace MVVM_Selection.ViewModel {
public class DashboardViewModel : INotifyPropertyChanged {
static DashboardViewModel instance;
readonly List<CountryStatisticInfo> countriesData;
CountryStatisticInfo selectedCountry;
public event PropertyChangedEventHandler PropertyChanged;
public static DashboardViewModel Instance {
get {
if (instance == null) instance = new DashboardViewModel();
return instance;
}
}
public List<CountryStatisticInfo> CountriesData {
get { return countriesData; }
}
public CountryStatisticInfo SelectedCountry {
get { return selectedCountry; }
set {
if (selectedCountry != value) {
selectedCountry = value;
OnPropertyChanged("SelectedCountry");
}
}
}
public void PopulateData(string filepath) {
countriesData.AddRange(CountriesInfoDataReader.Load(filepath));
selectedCountry = countriesData[0];
}
DashboardViewModel() {
countriesData = new List<CountryStatisticInfo>();
}
void OnPropertyChanged(string propertyName) {
PropertyChangedEventHandler propertyChangedEventHendler = PropertyChanged;
if (propertyChangedEventHendler != null)
propertyChangedEventHendler(this, new PropertyChangedEventArgs(propertyName));
}
}
class CountriesInfoDataReader {
static List<PopulationStatisticByYear> LoadStatistic(XElement populationDynamic) {
List<PopulationStatisticByYear> statistic = new List<PopulationStatisticByYear>();
foreach (XElement populationDynamicItem in populationDynamic.Elements("PopulationStatisticByYear")) {
int year = int.Parse(populationDynamicItem.Element("Year").Value);
long population = long.Parse(populationDynamicItem.Element("Population").Value);
double urbanPercent = double.Parse(populationDynamicItem.Element("UrbanPercent").Value, CultureInfo.InvariantCulture);
PopulationStatisticByYear popDynamicItem = new PopulationStatisticByYear(year, (double)population / 1000000.0, urbanPercent);
statistic.Add(popDynamicItem);
}
return statistic;
}
public static List<CountryStatisticInfo> Load(string path) {
XDocument doc = XDocument.Load(path);
List<CountryStatisticInfo> data = new List<CountryStatisticInfo>();
foreach (XElement countryInfo in doc.Root.Elements("CountryInfo")) {
string name = countryInfo.Element("Name").Value;
double areaSqKm = uint.Parse(countryInfo.Element("AreaSqrKilometers").Value);
List<PopulationStatisticByYear> statistic = LoadStatistic(countryInfo.Element("Statistic"));
CountryStatisticInfo countryInfoInstance = new CountryStatisticInfo(name, areaSqKm / 1000000, statistic);
data.Add(countryInfoInstance);
}
return data;
}
}
}
using System.Collections.Generic;
namespace MVVM_Selection.Model {
public class CountryStatisticInfo {
readonly string name;
readonly double area;
readonly List<PopulationStatisticByYear> statistics;
public string Name
{
get { return name; }
}
// Measured in millions of square kilometers.
public double Area
{
get { return area; }
}
public List<PopulationStatisticByYear> PopulationDynamics
{
get { return statistics; }
}
public CountryStatisticInfo(string name, double area, List<PopulationStatisticByYear> statistics) {
this.name = name;
this.area = area;
this.statistics = statistics;
}
}
public class PopulationStatisticByYear {
int year;
double populationMillionsOfPeople;
double urbanPercent;
public int Year
{
get { return year; }
}
// Measured in Millions of people.
public double Population
{
get { return populationMillionsOfPeople; }
}
public double UrbanPercent
{
get { return urbanPercent; }
}
public double RuralPercent
{
get { return 100 - urbanPercent; }
}
public PopulationStatisticByYear(int year, double populationMillionsOfPeople, double urbanPercent) {
this.year = year;
this.populationMillionsOfPeople = populationMillionsOfPeople;
this.urbanPercent = urbanPercent;
}
}
}
using MVVM_Selection.ViewModel;
using System.Windows;
namespace MVVM_Selection {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
var viewModel = DashboardViewModel.Instance;
viewModel.PopulateData(@"..\..\Data\Top10LargestCountriesInfo.xml");
DataContext = viewModel;
}
}
}