I'm new to MVVM, and I'm a bit in over my head here. English is not my preferred language, so please bear with me.
I'm trying to make a HMI for PLC. I'm supposed to connect to two different PLC, and present data from different datablocks in the PLCs. For simplicity let's talk about connecting only to one PLC, and getting data from only one datablock. The datablock has a repeating struct of data, in my solution I make each struct into a object.
For communications with the PLC I use Libnodave. MVVM Light for MVVM-thingies.
Model.
Contains the “recipe” for the PLCs struct. It also includes get-set-methods.
int _startByte;
string _name;
int _value1;
bool value2;
ViewModel.
Iherits from ViewModelBase, and has a Model-object as member. Public get-set-methods, wich raises propertychanged on set. Examples:
Public ViewModel(string name, int startByte)
{
_model = new Model{Name = name, StartByte = startByte};
}
public int Value
{
get{return _model.Value;}
set
{
if(_model.Value!=value)
{
_model.Value=value;
RaisePropertyChanged("Value");
}
}
}
CollectionViewModel.
ObservableCollection of ViewModels. Gets Models name and startbyte from ModelData.cs (a class with two arrays, name and startbyte). Using RelayCommands I've tested adding ViewModels to collection.
View.
Works for now, and will hopefully work later as well
My programs looks somewhat like this:
View
CollectionViewModel
ViewModel ModelData
Model
(ViewModel and ModelData don't know each other)
So, over to collecting data. My plan was to let the ViewModel have a reference to a PLC-object (this is where Libnodave comes in), and using the PLC-objects methods collect data. The PLC-object represents a connection to a PLC, and contains methods for writing and reading data. In the ViewModel, I would use the PLC-objects methods to collect data (and write data).
This means a lot of PLC-references, but locking will hopefully prevent crash. My problem is I can't figure out how to give the ViewModel a reference to a PLC-object. The PLC-object will also be used by other ViewModels, and there will be two different PLS-object, one for each PLC.
Is this a valid approach, or should I look in to something completely different?
If I'm understanding correctly, you have a PLC, with an array of data structures within it, and each of these data structures is going to be represented in your program by an object. Now multiply that by two since you have two PLCs.
For the sake of this post, let's call the class that represents one PLC
PLC
. Let's call each object that represents a single structure in that PLCPLCData
.Create a singleton class (or static class) that contains an array that holds your two
PLC
objects. EachPLC
object has an array (or List<> or ...) ofPLCData
objects.Now, your viewmodels just need to get hold of the instance of the singleton or static class, which is easy to do.
If you're using multithreading (using one thread per PLC to collect the data),
BlockingCollection
might be a good choice as a data structure for your objects.