DataGrid
inputs to cause changes automatically (MVVM) I am trying to create a simple application in which I have a charting tool that accepts collections as series to be plotted. My plan is to have an input DataGrid
that is bound to a collection which can be populated manually.
Based on the values inside the DataGrid
, I would then like to simultaneously populate a different collection that represents the definite integral of whatever function is being plotted, in other words a different function that shows the area between the input function and the x-axis.
As the DataGrid
is updated, I would like to use MVVM to responsively update the chart as well, to display changes in both the input data and the output data.
I have created a gist that contains my implementations so far .
In short, the application has the following components:
Coordinate<T, U>
that has an X and Y property (and uses INotifyPropertyChanged
) ObservableCollection<Coordinate<double, double>>
for plotting purposes NumericalCalculator
for executing numerical methodsIn the WPF chatroom, Maverik suggested I could use value converters to let WPF do the heavy lifting, so I have written the following converters:
CoordinateSeriesToStringConverter
converts a collection of coordinates to a string where all the coordinates are separated by comma's FunctionToEquallySpacedConverter
attempts to convert a collection of coordinates into a new collection containing some n
number of equally spaced coordinates FunctionToIntegralConverter
attempts to integrate the input function (collection of coordinates) to its numerical integral between two bounds (currently does not integrate yet, for testing purposes) DataGrid
's items source's elements? I have gone the value converter route, but it turns out that even with INotifyPropertyChanged
implemented on the elements of my bound ObservableCollection
, those changes do not activate the converters.
I've already gotten a nice answer from sparedev
with a different approach, which I will likely try out as well, but I'm still curious how I could solve the value converter issue. I'm sure that if I get that sorted out, both options are equally viable.
UPDATE: I've tried sparedev's method, but even with INotifyPropertyChanged
, manipulating the DataGrid
's items from the UI does not raise any new events. Adding new rows or deleting them raises a CollectionChanged
event, but unfortunately this alone does not let me update the plots responsively yet.
Let's register on CollectionChanged event and update result collection, see below.
public MainViewModel()
{
InputCollection.CollectionChanged += Items_CollectionChanged;
}
private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach (var i in e.NewItems)
{
var c = i as Coordinate<double, double>;
ResultCollection.Add(c);
c.PropertyChanged += Item_PropertyChanged;
}
}
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
foreach (var i in e.OldItems)
{
var c = i as Coordinate<double, double>;
ResultCollection.Remove(c);
c.PropertyChanged += Item_PropertyChanged;
}
}
}
private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var c = sender as Coordinate<double, double>;
Console.WriteLine(c.X + " " + c.Y);
}
May be your Coordinate class should implement INotifyPropertyChanged interface. During setting X or Y property PropertyChanged should raised.
public class Coordinate<T, U> : IComparable<Coordinate<T, U>>, INotifyPropertyChanged
where T : IComparable<T>
where U : IComparable<U>
{
public Coordinate() { }
public Coordinate(T x, U y)
=> (X, Y) = (x, y);
public event PropertyChangedEventHandler PropertyChanged;
private T _X;
public T X
{
get => _X;
set
{
if (value.CompareTo(_X) != 0)
{
_X = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(X)));
}
}
}
private U _Y;
public U Y
{
get => _Y;
set
{
if (value.CompareTo(_Y) != 0)
{
_Y = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Y)));
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.