I am trying to bind an ObservableCollection of data from my ViewModel to a Devexpress 2D chart in a view. I know that the virtual machine is associated with the DataContext view because I have a window title associated with the property in the virtual machine, and that is correct when I run the program. The collection is created correctly, I see that all objects are created, have values ββand are added to the collection.
Chart information is simply not displayed. The diagram shows only the information that should be attached to it. I assume this is due to the line in my XAML, but I just don't know what it is.
Here is the output error:
System.Windows.Data error: 40: BindingExpression path error: The "Snapshots" property was not found on the "object" '' ChartElementPanel '(Name =' ') ". BindingExpression: Path = DataContext.Snapshots; DataItem =' ChartElementPanel '(Name = ''); target element is "StockSeries2D" (HashCode = 24500892); target is "DataSource" (type "Object")
DevExpress Version - 10.1.9
EDIT: It seems I know what the problem is. StockSeries2D DataContext = DevExpress.Xpf.Charts.ChartElementPanel So when I use
DataSource="{Binding Path=DataContext.Snapshots}"
This really points to DevExpress.Xpf.Charts.ChartElementPanel, and since it does not contain the Snapshots property, an error occurs.
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="200" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<dxc:ChartControl Name="chartControl1">
<dxc:ChartControl.Diagram>
<dxc:XYDiagram2D>
<dxc:XYDiagram2D.Series>
<dxc:StockSeries2D DataSource="{Binding DataContext.Snapshots}" HighValueDataMember="High" LowValueDataMember="Low" CloseValueDataMember="Last" ArgumentScaleType="DateTime" ArgumentDataMember="TimeStamp">
<dxc:StockSeries2D.PointOptions>
<dxc:PointOptions dxc:FinancialSeries2D.ValueToDisplay="HighValue" />
</dxc:StockSeries2D.PointOptions>
<dxc:StockSeries2D.Model>
<dxc:ArrowsStock2DModel />
</dxc:StockSeries2D.Model>
</dxc:StockSeries2D>
</dxc:XYDiagram2D.Series>
<dxc:XYDiagram2D.AxisX>
<dxc:AxisX2D>
<dxc:AxisX2D.DateTimeOptions>
<dxc:DateTimeOptions Format="ShortTime" />
</dxc:AxisX2D.DateTimeOptions>
</dxc:AxisX2D>
</dxc:XYDiagram2D.AxisX>
<dxc:XYDiagram2D.AxisY>
<dxc:AxisY2D>
<dxc:AxisY2D.Range>
<dxc:AxisRange dxc:AxisY2D.AlwaysShowZeroLevel="False" />
</dxc:AxisY2D.Range>
</dxc:AxisY2D>
</dxc:XYDiagram2D.AxisY>
</dxc:XYDiagram2D>
</dxc:ChartControl.Diagram>
</dxc:ChartControl>
</Grid>
ViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
ObservableCollection<ISnapShot> _snapShots;
string _windowTitle;
public MainWindowViewModel()
{
_snapShots = new ObservableCollection<ISnapShot>();
LoadSnapshots();
WindowTitle = Snapshots.First().Symbol;
}
public ObservableCollection<ISnapShot> Snapshots
{
get { return _snapShots; }
}
public String WindowTitle
{
get { return _windowTitle; }
set { _windowTitle = value; OnPropertyChanged("WindowTitle"); }
}
private void AddSnapshot(ISnapShot snapshot)
{
_snapShots.Add(snapshot);
}
private void LoadSnapshots()
{
int counter = 0;
while (counter < 5)
{
ISnapShot s = new Snapshot()
{
TimeStamp = DateTime.Now,
Symbol = "XYZ",
High = (counter + 1) * 5,
Low = (counter + 1) * 2,
Last = (counter + 1) * 3
};
_snapShots.Add(s);
counter++;
Thread.Sleep(1000);
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
View:
public partial class MainWindow : Window
{
private MainWindowViewModel _vm;
public MainWindow(MainWindowViewModel vm)
{
InitializeComponent();
_vm = vm;
this.DataContext = _vm;
}
}
applications:
public partial class App : Application
{
private void OnStartup(object sender, StartupEventArgs e)
{
MainWindowViewModel vm = new MainWindowViewModel();
Views.MainWindow view = new Views.MainWindow(vm);
view.Show();
}
}