How to dynamicly databind the itemsource of WPF Toolkit chart to a public property?
.net, charts, wpf
Solution
wpf bind to public properties so you need
public List<KeyValuePair<string, int>> ValueList {get; private set;}
EDIT: here some more information about using the chart control.
EDIT2:
ItemsSource="{Binding ValueList}"
this can not work because you have to create ValueList as a property first and second you need to set the datacontext to an instance of DeviceInput (like you did in your mainwindow.cs).
EDIT3: quick and dirty example, simply copy&paste and if you hit the button data will be added
viewmodel
public class Input
{
public ObservableCollection<KeyValuePair<string, int>> ValueList { get; private set; }
public Input()
{
this.ValueList = new ObservableCollection<KeyValuePair<string, int>>();
ValueList.Add(new KeyValuePair<string, int>("Developer", 60));
ValueList.Add(new KeyValuePair<string, int>("Misc", 20));
ValueList.Add(new KeyValuePair<string, int>("Tester", 50));
ValueList.Add(new KeyValuePair<string, int>("QA", 30));
ValueList.Add(new KeyValuePair<string, int>("Project Manager", 40));
}
public void Add(KeyValuePair<string, int> data)
{
ValueList.Add(data);
}
}
window.cs
public partial class MainWindow : Window
{
private Input data;
public MainWindow()
{
data= new Input();
InitializeComponent();
this.DataContext = data;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.data.Add(new KeyValuePair<string, int>("XXX", 27));
}
}
xaml
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,-28,0,28">
<Grid Height="921">
<chartingToolkit:Chart Height="262" HorizontalAlignment="Left" Margin="33,0,0,620" Name="columnChart" Title="Column Series Demo" VerticalAlignment="Bottom" Width="360">
<chartingToolkit:ColumnSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList }" />
</chartingToolkit:Chart>
<chartingToolkit:Chart Name="pieChart" Title="Pie Series Demo" VerticalAlignment="Top" Margin="449,39,43,0" Height="262">
<chartingToolkit:PieSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList }" IsSelectionEnabled="True" />
</chartingToolkit:Chart>
<chartingToolkit:Chart Name="areaChart" Title="Area Series Demo" VerticalAlignment="Top" Margin="33,330,440,0" Height="262">
<chartingToolkit:AreaSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList }" IsSelectionEnabled="True"/>
</chartingToolkit:Chart>
<chartingToolkit:Chart Name="barChart" Title="Bar Series Demo" VerticalAlignment="Top" Margin="449,330,43,0" Height="262">
<chartingToolkit:BarSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList }" IsSelectionEnabled="True"/>
</chartingToolkit:Chart>
<chartingToolkit:Chart Name="lineChart" Title="Line Series Demo" VerticalAlignment="Top" Margin="33,611,440,0" Height="254">
<chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList }" IsSelectionEnabled="True"/>
</chartingToolkit:Chart>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="342,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</ScrollViewer>
Problem
How can you dynamically update the datasource of a WPF ToolKit chartcontrol? In the following example I update the TextBlock.Text property succesfully with {Binding SomeText} and setting the DataContext of the MainWindow to the property Input. (Please see the code below) TextBlock.Text is binded to Input.SomeText and the Chart is suppose to use Input.ValueList as a datasource. The chart remains empty though. I can fill it once with placing ``` lineChart.DataContext = Input.ValueList; ``` in the Main Window constructor and set the binding in XAML to ItemsSource="{Binding}". But this only works at startup, it doesn't update when you click a button for example. I want to update the chart while the application is running with new incoming data. I have the following XAML: ``` <chartingToolkit:Chart Name="lineChart"> <chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding ValueList}"> </chartingToolkit:LineSeries> </chartingToolkit:Chart> <Button Width="100" Height="24" Content="More" Name="Button1" /> <TextBlock Name="TextBlock1" Text="{Binding SomeText}" /> ``` With code: ``` class MainWindow { public DeviceInput Input; public MainWindow() { InitializeComponent(); Input = new DeviceInput(); DataContext = Input; lineChart.DataContext = Input; Input.SomeText = "Lorem ipsum."; } private void Button1_Click(System.Object sender, System.Windows.RoutedEventArgs e) { Input.AddValues(); } } public class DeviceInput : INotifyPropertyChanged { private string _SomeText; public string SomeText { get { return _SomeText; } set { _SomeText = value; OnPropertyChanged("SomeText"); } } public List<KeyValuePair<string, int>> ValueList {get; private set;} public DeviceInput() { ValueList = (new List<KeyValuePair<string, int>>()); AddValues(); } public void AddValues() { //add values (code removed for readability) SomeText = "Items: " + ValueList.Count.ToString(); OnPropertyChanged("ValueList"); } public event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged; private void OnPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } ``` SomeText gets updated and to make sure the ValueList changes I place ValueList.Count in the textblock and you can see the count rising as it should, however the Chart remains the same. So this results in 1 succesfull binding (but doesnt update): ``` lineChart.DataContext = Input.ValueList; ItemsSource="{Binding}" ``` This doesn't bind at all: ``` ItemsSource="{Binding ValueList}" ```