How to bind a chart axis to a specific List () index?

I am trying to create a chart using the WPF Toolkit, where the Y-axis is updated with the values ​​in List() . I am trying to access a value using a specific index. Currently binding to the List() index rather than the int creates "There is no suitable axis for plotting the dependent value." an exception.

Here is what I still note with my attempt to get DependentValuePath to access the index:

 <Charting:LineSeries VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=MemoryStats}" IndependentValuePath="Timestamp" DependentValuePath="ByteCount[0]" Title="Data Points"> 

This is what the MemoryStats values ​​in the code consist of:

 public List<int> ByteCount { get; set; } public DateTime Timestamp { get; set; } 

The graph works fine when the LineSeries in XAML has the DependentValuePath="ByteCount" property, and when codebehind uses a simple int:

 public int ByteCount { get; set; } public DateTime Timestamp { get; set; } 

How do I bind it to a List() index, not an int ?

EDIT

I managed to capture a specific value in the list from the code behind by naming its index, but when creating a diagram, several LineSeries will be generated dynamically generated. I would like to bind each of them to the List<int>() index, which I recreate every second or so.

Here is the complete method that MemoryStats uses to update the user interface. It works by updating all LineSeries Y values ​​to a single int byte set, so currently all lines look the same.

  public class MemorySample { public static MemorySample Generate(List<int> dataPoints) { return new MemorySample { ByteCount = dataPoints[0], Timestamp = DateTime.Now }; } public int ByteCount { get; set; } public DateTime Timestamp { get; set; } } 

Of course, I would like all LineSeries be different. I would like the X axis of each LineSeries chart to be TimeStamp (so they all have the same TimeStamp), and different LineSeries have their Y axis values ​​using List() integers, each using a separate List() index

I will try to implement a type converter, but I'm not quite sure when / where to do it.

EDIT 2

I got it to work the way I wanted it! I found a lot of help from this SO question regarding using multiple series in a line chart.

It seems that the type converter will work the same way as the Shimrod question. However, what I ended up setting up the ItemSource ItemSource ItemSource to the index and then ItemSource contents of that index.

So here is what the LineSeries looks LineSeries :

  <Charting:LineSeries VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding [0]}" IndependentValuePath="X" DependentValuePath="Y" Title="Data Points"> </Charting:LineSeries> 

Notice the index in the ItemSource binding. In the code behind, I set the DataContext of the control to an ObservableCollection , which contains an object that inherits from "IList" (which you can use any object that does this), and this object contains an object that contains the X and Y properties.

  public ObservableCollection<InheritsFromIList<ObjectWithXandYProperties>> VariableDataContextIsSetTo { get; set; } 

Access to a specific ObservableCollection index will return a list. Then the items in this list are displayed on the chart.

+4
source share
1 answer

The easiest way to do this is to add a property to your class, which will be an int value of List .

eg.

 int val { get { return ByteCount[0]; } } 

Or you can also create a converter that takes the list as a binding and index as a parameter and returns the desired value.

For example (I have not tried this):

 public class ElementOfListConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is IList && parameter is int) { var lst = value as IList; int pos = (int)parameter; if (lst.Count >= pos) { return lst[pos]; } } return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

Edit

These are the steps to use the converter:

  • Create a class (ElementOfListConverter) as shown above.
  • Add a new xml namespace indicating the location of your converter. For instance. xmlns:local="clr-namespace:WpfApplication2"
  • In the resources of your window (or UserControl) add a link to your converter, for example:

     <Window.Resources> <local:ElementOfListConverter x:Key="ElemOfList" /> </Window.Resources> 
  • In your binding, specify the converter to use (using its key) {Binding YourElement, Converter={StaticResource ElemOfList}, ConverterParameter=0}

About this method is that you can specify the index of the element directly in xaml. You can also bind this value to another value using MultiBinding and MultiValueConverter . (see this question on SO if you need more info.

+1
source

Source: https://habr.com/ru/post/1494575/


All Articles