Databinding #2 and ItemsTemplate: why we use observable collection and the 1st try to give a representation of an object

This is the 2nd article about databinding.
The 1st can be found here and the 3rd here.
As the name says, observable collection is a collection that send an event when items are added or removed from it.
This is really useful in automation for manage recipes for examples, but basically you can manage everything: it can be also a collection of machines, a collection of silos, and so on.
I use observable collection a lot for charts and to manage big lists of similar items.

This is an example on how to use an observable collection:
Let's suppose that i have my usual tank, like in the previous example, and i want to add some new liquids to the listbox, and i want also to remove them.
Of course i want to see changes in real time, and i want to write as less code as possible.

So as usual i define my data class:
class Liquid
    {
        public string Name { get; private set; }
        public SolidColorBrush LiquidColor { get; private set; }        
        public Liquid(string name, Color color) 
        {
            this.Name = name;
            this.LiquidColor = new SolidColorBrush(color);            
        } 

And my observable collection of liquids, with 3 samples :
    class LiquidCollection : ObservableCollection
    {
        public LiquidCollection() 
        {  
            this.Add(EmptyCilinder());
            ...
            this.Add(OrangeLiquid());      
        }
        private Liquid EmptyCilinder()
        {  return new Liquid("Empty Cilinder", Colors.Gray);  }
       ...
        private Liquid OrangeLiquid()
        {  return new Liquid("Orange liquid", Colors.Orange); }        
    }

Then i add a custom color collection where i cover all the colors:
class CustomColorCollection : ObservableCollection
    {
        public CustomColorCollection() 
        {
            this.Add(new SolidColorBrush(Colors.Aqua));
            ....
            this.Add(new SolidColorBrush(Colors.Gold));
        }
    }

Then i place 2 listbox, 1 textbox and 2 buttons in the User Interface, in the code behing as usual i set the datacontext:
public MainWindow()
        {
            InitializeComponent();
            lstSelectColor.DataContext = new LiquidCollection();
            lstLiquidColors.DataContext = new CustomColorCollection();
        }

and the 2 buttons callback:
private void btnAddLiquid_Click(object sender, RoutedEventArgs e)
        {
((LiquidCollection)lstSelectColor.DataContext).Add(new Liquid(txtNameNewLiquid.Text,    ((SolidColorBrush)lstLiquidColors.SelectedItem).Color));
}

        private void btnRemoveLiquid_Click(object sender, RoutedEventArgs e)
        {
((LiquidCollection)lstSelectColor.DataContext).Remove((Liquid)lstSelectColor.SelectedItem);
}

And this is the UI (to binding items refere at the post of databinding #1):

Compiling and running i obtain what i want, so i have a list of colors and a list of liquids that i can update, adding or removing.


The only problem is that the list of color sux. In this case we need to use an ItemTemplate to give a representation of an object Color in the listbox.

A good way can be represent it on a rectangle, and this could be done in this way:
If we compile and debug we obtain something better, that it's similar to this:

I think that doing this with winforms it's really hard, but with WPF and a bit of imagination it will take not so much time, and the final users will be happier than to see a listbox with "Green - Dark Green - Light Green - Purple - and so on..."

As usual you can find the full solution here:
http://mesta-automation.com/Downloads/databinding2.rar

Comments on code are good or bad ?

In this days i read a discussion on a forum between some programmers and they were discussing about "Write or not to write comments on programs".
The discussion result wasn't so obvious, because many of them said that comments were not only useless, but also dangerous, and in the most of cases it would be better if they weren't ever written.

This is an example of bad comments:
channel++;   //increment channel 

The good thing about this line was that both the code and the comment agreed (experience shows this is quite often not the case). The bad thing about this code is that they are both wrong, the problem being that the original coder didn't understand the difference between channel and timeslot [2] and chose the wrong variable name. Fortunately, when he (or someone who came along later) realised the mistake he used a snazzy re-factoring tool that avoids the problems with global "find and replace" and understands the code enough to only change the relevant variable name and not other occurrences of the string or the same name in another scope. The code now reads:
 timeslot++;      //increment channel 

You might ask why the re-factoring programmer didn't change the comment to match and it was because he wasn't looking at that particular line, but at this one:
 uint32_t channel; // I think this is probably timeslot, not channel. 

The first person to come along realised the poor choice of variable name and "fixed" it by adding a comment. The second decided it would be better to change the variable name. Obviously, the second programmer believes in saying it in the code and disregarding comments, because the changed line now reads: uint32_t timeslot; // I think this is probably // timeslot, not channel. 

So what's the truth about comments? is it better to write them or not ?
Another example can be this:
r = n / 2;
while ( abs( r - (n/r) ) > t ) {
  r = 0.5 * ( r + (n/r) );
}
System.out.println( "r = " + r );

Any idea what that bit of code does? It's perfectly readable, but what the heck does it do? Let's add a comment.
// square root of n with Newton-Raphson approximation
r = n / 2;
while ( abs( r - (n/r) ) > t ) {
  r = 0.5 * ( r + (n/r) );
}
System.out.println( "r = " + r );
That must be what I was getting at, right? Some sort of pleasant, middle-of-the-road compromise between the two polar extremes of no comments whatsoever and carefully formatted epic poems every second line of code? Not exactly. Rather than add a comment, I'd refactor to this:
Codice:
private double SquareRootApproximation(n) {
  r = n / 2;
  while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
  }
  return r;
}
System.out.println( "r = " + SquareRootApproximation(r) );
I haven't added a single comment, and yet this mysterious bit of code is now perfectly understandable.

This guy (http://www.makinggoodsoftware.com), that got a blog where he writes about tips to make a good code, wrote an interesting page on "writing comments or not", and you can find his article here:
http://www.makinggoodsoftware.com/2009/06/06/comments-are-evil/
where he basically says that:
  • The worst code is: Bad code without comments.
  • Bad code is: Bad code with comments.
  • The average code is: Average code with comments.
  • Good code is: Good code with a few comments…
  • …but… Great code doesn’t need comments!!!
And he gives some advices on how to increase the readiblilty:
http://www.makinggoodsoftware.com/2009/06/22/how-to-write-readable-code/
and
http://www.makinggoodsoftware.com/2009/06/04/10-commandments-for-creating-good-code/

It's important to keep improving our code, to help us and other people mantaining the applications.

Why WPF for automation? Databinding #1

This is the 1st article of 3 about DataBinding.
Check the 2nd here and the 3rd here.
It's clear that WPF has a better graphic and appearence, with all of those gradients, animations and so on, but what are the real benefits for a programmer ?
The Page-Switch application was a good start, but why should we learn xaml (that is also a new concept and quite hard) instead of using our loved winforms and GDI ?
I think that the best reason to learn WPF is that it permits to build easy-to-use and self-explained interfaces for operators, with really little code-writing.
Let's suppose that i wanted to display lisbox of radiobuttons, or treeview of checkbox... it would be hard to write this controls in winforms and they would have a lot of bugs inside.
That's why winforms got a lot of custom control (not free of course) around the ne.
In WPF, thanks to a pattern that separates graphics from code-behind, it's possible to have complex controls with not many troubles.
Model - View - View Model is the pattern that permit to developpers to separate physically the User Interface part from the code behind, and this is possible because of a powerful concept on wich WPF is based: DataBinding.

Basically Model - View - View Model consist in this:
Model : all the codebehind, services and so on  that permit to the application to run (like the code that was written in winforms)
View: the User Interface, all the code that we write in XAML.
View Model: this is new, this is the layer between UI and code behind, it's based on data binding and it save us a lot of code that can have a lot of bugs, and it's usually the code that connects the UI with business objects. One important fact to keep in mind is that in automation we have tons of controls to display tons of values, infact usually little scada and HMI displays timers, analogic values, alarms and some output status, but in bigger ones there are a lot of other factor too, like keeping track of values while time changes and so on. View Model permit to connect the User Interface with Objects, that can come for example from an OPC Client, with really little code.

To explain it better i'll make an example:
I want to fill a tank (here is designed really poorly) with a liquid that i select from a listbox, and i want to see the tank changing color when i change its content.
I don't want to use events and a lot of code to do this thing, also i want to define a class Liquid and a collection of them, because they can change during production, and i would like to update them easily.

So let's write the liquid class:
using System.Windows.Media;
namespace SilosSample.Data
{
    class Liquid
    {
        public string Name { get; private set; } //name of liquid       
        public LinearGradientBrush LiquidColor { get; private set; } //color
       

        public Liquid(string name, GradientStopCollection _gradStopCollection)
        {
            this.Name = name;
            this.LiquidColor = new LinearGradientBrush(_gradStopCollection);
        }
    }
}


Then fill the collection (in reality members would be taken from a database, with more parameters than a name and a color)
using System.Collections.ObjectModel;
using System.Windows.Media;
using SilosSample.Data;
namespace SilosSample.ViewModel
{
    class LinearGradientCollection : ObservableCollection
    {
        public LinearGradientCollection()
        {
            this.Add(EmptyCilinder());
            this.Add(Water());
            this.Add(OrangeLiquid());           
        }
        private Liquid EmptyCilinder()
        {
            GradientStopCollection gradStopCollection = new GradientStopCollection();      
            gradStopCollection.Add( new GradientStop(Colors.LightGray,0));
            gradStopCollection.Add(new GradientStop(Colors.Black, 0.992));
            gradStopCollection.Add(new GradientStop(Colors.DarkGray, 0.125));
            gradStopCollection.Add(new GradientStop(Colors.Gray, 0.802));
            return new Liquid("Empty Cilinder", gradStopCollection);
        }
        private Liquid Water()
        {
                GradientStopCollection gradStopCollection = new GradientStopCollection();
                gradStopCollection.Add(new GradientStop(Colors.LightCyan, 0));
                gradStopCollection.Add(new GradientStop(Colors.DarkBlue, 0.992));
                return new Liquid("Water", gradStopCollection);
        }
        private Liquid OrangeLiquid()
        {
                GradientStopCollection gradStopCollection = new GradientStopCollection();
                gradStopCollection.Add(new GradientStop(Colors.LightCoral, 0));
                gradStopCollection.Add(new GradientStop(Colors.Orange, 0.992));
                return new Liquid("Orange liquid", gradStopCollection);
        }
    }
}

And now i want to connect(to bind) my user interface to the collection.
this is done in this way:
define a datacontext (it's the datasource, in this case my collection of colors) in the codebehind  for the listbox:
public partial class MainWindow : Window
    {     
        public MainWindow()
        {
            InitializeComponent();
            lstSelectColor.DataContext = new LinearGradientCollection();
//my collection    
        }
    }

Then write the User Interface and bind the properties that you want to control directly with XAML:
in this case i wanted that my listbox contains the collection (so datasource was in bind with all the datacontext), i wanted to display only the name (displayMemberPath is always the same as old one), and i wanted to synchronize the current element with the rest of the window, so i can update my controls without writing a single line of code.
Then to fill the silos there, i just need to bind the property "Fill" at the selected item of the listbox, just as it's written in the code.


This is really a simple example, but it's amazing how powerful it is WPF and how little code you have to write to obtain sophisticated controls.
In a future post i'll cover also the interface "INotifyPropertyChanged", that permit to update an item in a collection and also the items in bind with it (example: i have a collection of silos and i want to update the color of one of them).

As usual i add the complete solution:http://www.megaupload.com/?d=IQUX2NVX

To see more about ObservableCollection, INotifyPropertyChanged and normal collections, see this post: http://www.codeproject.com/KB/silverlight/SLListVsOCollections.aspx

Multi Page application with WPF (HMI-like)

Dear reader, this is an old version of the article. You can find the new version on my new blog.
[UPDATE 18/3/2012] The source code can be downloaded here: http://mesta-automation.com/Downloads/HmiLike.rar

Hi,
now that we got the code to establish connection between Plc and Pc, we want to do free HMI, SCADA, MES and so on.
So we need to put in a list what an HMI (the easier to start with) application must contain:
- Buttons, textbox, labels and so on to permit the configuration and manteinance of the machine to the operator.
- Graphs in Real Time, to control temperatures, pressures, levels and so on...
- Alarm system, that includes a database to store events, alarms and so on.
- Menu (with password?) that permits the access at the differents parts of the plant at variuos kind of personal.
- Some graphic items or designs, that change color when change status in real.

This things are a lot, so we have to forget to build an HMI using the classic windows interface with a MenuBar and a Toolbar, but we need a multipage application (like a site), where pages are accessible by buttons, and sometimes pop-up. We need an appliaction that can support also industrial panels with touch-screen.
This guy got a good idea: http://azerdark.wordpress.com/2010/04/23/multi-page-application-in-wpf/
He decided to use one window and to use the system of change page, provided by WPF, to load different UserControls, that can be full pages or controls shared by the entire application.
This is what i did:
- i created a new WPF application, opened the codebehind of MainWindow, and added the next code



Then wrote the class Switcher:
 - Created a user control that will be used as menu (this is a grid with 4 buttons)

- In the code behind i wrote the code to switch pages

 
- I added to every page the menu control and i wrote on constructor of MainWindow the 1st page that has to be displayed (PageControls in my case)



Hope it's useful. The complete solution can be found here: http://mesta-automation.com/Downloads/HmiLike.rar

OPC Client c# .Net Sample (RSLinx OPC server)

Hi, a big problem about connecting PLC to PC is the "from where should i start?".
And that's why i suppose people choose commercial SCADA instead of .Net (they already has drivers and so on).
Well, if it was for winforms, i would agree that winforms sucks, they got a lot of bugs and so on, so i would choose a commercial SCADA too.
But since WPF and Silverlight was released, .Net is really more more powerful and beautiful, the code became easier with the binding system and industrial PCs + OPC servers cost always less (and sometimes it's possible to find free drivers).

This post is an example of communication with RSLinx OPC Server (but i use OPC Foundation libraries so the process is the same for every OPC server).


So let's strart by adding a reference to the OPC Foundation dlls:
- OpcNetApi.Com.dll
- OpcNetApi.dll
- OpcNetApi.Xml.dll

Then create Items that are shared for the all the form (or the project)
Then create a button to connect (or just place the code after InitializeComponent(); if you want to autoconnect when the program starts)
Set the URL (in this sample there is the one of RSLinx) then add a group, add some items with theyr connection string, set the update time and the callback for the items that you want to read, then set a group for writings.


 This is the sample callback where i assign values that i read to a custom object.
Remember that the GUI and the OPC client runs on two different threads, so it's needed to use anonymous method for this (just use like is written in the sample).
With WPF and INotifyPropertyChanged it's not needed this.
You can just bind all your objects to the GUI items property, and this is really amazing and simple.
 This is the way that i found to write a single word, basically i create a new one, i check if in the write group there is already one of them, else i add it.
 Writing was always a problem for me, but when i found this way, i got all i needed

This is a sample of how i write from a button reading a textbox


IMPORTANT UPDATE: This code is written on a Micrologix / SLC platform and it reads only integer values, so when i read a value it's supposed to be a 16-bit word: that's why i cast it to (short). Remember that if you read a REAL value (F8:0 for example) you sould cast it to float and if you read from Controllogix or CompactLogix, you have to convert it to (int) because they are 32-bit words.

This is the complete solution:

http://www.mesta-automation.com/Downloads/OPC%20Client.rar

This is another link for a Twincat OPC Server, that is similar to the RSLinx.
http://infosys.beckhoff.com/content/1033/tcopcserver/html/sample1_netapi.htm?id=18186

UPDATE: i wrote a recent post here where i wrote a full sample with WPF and an OPC client in c#. watch it here: http://mestaa.blogspot.com/2010/12/wpf-and-opc-full-sample-project-with.html

[UPDATE #2]: i made a video that explains how to use the code provided: check it here: http://www.mesta-automation.com/opc-client-with-c-an-how-to-video/

WPF Toolkit Chart with Scrollbar

At the moment i'm working on WPF Toolkit Chart, because i need to visualize some dynamic collection.
Most of the times these collections came from a large database and one of the problem i met it was this:



Pretty awful of course, and so i had to add a scrollview.

This is easy to do, just include your chart declaration in XAML into a ScrollViewer, and then group everything into a border, a grid or a panel.
Example:



To enable the scrollbar it's needed to se a custom width to Chart,like this way.



and this will do the trick.



Complete solution for Visual Studio 2010 is here:
http://www.mesta-automation.com/Downloads/WPF%20Scroll%20Chart.rar