Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Multilanguage applications with C# with database support


As i wrote in an earlier post, the best way to realize a multilanguage application is to get translated text from a database.
This because even if you know 2 or 3 languages, you should be able to sell the application worldwide without even care on what language it is realized.
I think that one of the best database to use for translations is MS Access, because every translator has an office suite installed on his PC, and for him makes no difference translate on Excel or Access, but if you ask him to translate your sentences on "a random SQL data viewer", it can be a pain.
To support multilanguage in my apps i use a method that, given the name of control, returns a string containing the translated text, like:
lblSample.Content = Translation.GetString("lblSample");
The reference to the culture is contained inside Settings, and that's where i modify my language preferences, so when i load the program i know automatically what language i should use.
You can find the link for a working example at the bottom of the page.

To realize a multilanguage selection you need:
- a listbox containing the list of languages,
- an "Apply" button
Features:
- The listbox should automatically detect the new languages
- The application should change not only the texts, but also date/time format, right to left writing and so on.

1#: Create a database file with access like in the sample and add it to the project:

2#: Download the translation class from
here
and paste it in your project,
or you can download the class with the working sample here:
http://www.megaupload.com/?d=H5ISA83P

3#: Add the current culture field on "Settings": this field will be used on all the project to set the national preferences.

4#: Customize the translation class modifying the namespace and the table rererences, if you modified them.
using ChangeLanguage.Properties; // modify the namespace with your project name
[...]
//connection string
        private static DatabaseResourceManager databaseResourceManager = new DatabaseResourceManager(settings.translationsConnectionString);    // here the connection string is declared inside settings; you can declare your own here.
[...]
OleDbCommand command = new OleDbCommand("Select * From Translations"); // Here there is the reference to table name
[...]
command.CommandText = "SELECT [key], [" + language + "] " + "FROM Translations"; // Here there is another reference to table name

5#: Create the GUI like in the example:
if you use xaml you can use this code:
    
        
        
        

6# Then in the main window you can write methods to fill the language comboBox
        /// 
 Detects languages in database and fill the listbox 
        private void LoadCmbItems()
        {
            try
            {
                List cultureList = Translations.GetCultureList();
                listLanguages.ItemsSource = cultureList;
                listLanguages.SelectedItem = settings.currentCulture;
                Date = DateTime.Now;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Language Database error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
and to load / change texts (but usually i do this only on the launch of application)
        private void SetTextsInCurrentLanguage()
        {
            this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
            LoadCmbItems();
            lblLanguages.Content = Translations.GetString("lblLanguages");
            btnApply.Content = Translations.GetString("btnApply");
            btnButton.Content = Translations.GetString("btnButton");
            lblLabel.Content = Translations.GetString("lblLabel");
            lblDateTime.Content = Translations.GetString("lblDateTime");
        }
You can see that it's really simple to extract translation with this method, it's just needed that you pass the name of the control to the method GetString to receice the translated Content.

7#: Once you wrote all translations, you can update the constructor of the main window to load the localized language and settings:
            Thread.CurrentThread.CurrentCulture = settings.currentCulture;
            Thread.CurrentThread.CurrentUICulture = settings.currentCulture;
            this.DataContext = this;         

            InitializeComponent();

            SetTextsInCurrentLanguage();          
and also create the button "Apply", that basically changes the settings (and in the example refresh the GUI also) :
        private void btnApply_Click(object sender, RoutedEventArgs e)
        {
            settings.currentCulture = (CultureInfo)listLanguages.SelectedItem;
            Thread.CurrentThread.CurrentCulture = settings.currentCulture;  //not so good to see... just to explain how it works
            Thread.CurrentThread.CurrentUICulture = settings.currentCulture;//you should force the user to re-initialize the program
            SetTextsInCurrentLanguage();
        }

You can download the full example here:
http://mesta-automation.com/Downloads/changeLanguage.rar
and read the full documentation here:
http://en.csharp-online.net/Localization_Like_the_Pros

Disclaimer
The sample code described herein is provided on an "as is" basis, without warranty of any kind, to the fullest extent permitted by law. Mestaa.blogspot.com does not warrant or guarantee the individual success developers may have in implementing the sample code on their development platforms or in using their own Web server configurations.

Standard colors on HMI

Dear reader, this is an old version of the article. You can find the new version on my new blog.

The lack of a standard on what colors use on HMI systems is a serious problem. After watching many applications and searching for a standard, i noticed that the most of panels' graphic pages depended on taste of the engineer that realized it.
It's not the first time that i see purple buttons, blue leds and green backgrounds.
Even if there isn't a written standard on what colors you should choose, i searched for the best ways to realize graphic page and keeps updating myself on making HMI colors as helpful as possible.
This is the standard that i use as much as i can:
  • Led : green for active, gray for inactive, red for alarm.
  • Reserve leds: gray for inactive, red for alarm/reserve.
  • Motors and valve: green for active, gray for inactive, red for alarm
  • Pipes and tanks: cyan for water, gray empty, other colors if acids or special liquids.
  • Momentary buttons: all grays and possibly with windows style and an image associated. All buttons must have a description (don't use only images, better use only description if you are forced to choose).
  • Toggle buttons: i like UP-DOWN switch levers. A button that stays pushed isn't a good way on how to represent a switch.
  • Alarm banner and log: Red (everything in red should be associated to something wrong)
  • Background: gray for numerous reasons, like it doesn't hurt eyes, no problem if there is low light of too much light, all operators are used to see gray backgrounds, gray means inactive - nothing wrong.
  • Animations: i use them only when i have to attract the attention of the operator, usually for alarms status or to pay attention at some particular operation. An abuse of animation distract the operator from it's job, so it should be for a good reason (NOT FOR A LOGO!). I don't even like to represent bottles that get filled and capped (for example), because the operator is not blind and can see what's happening inside the filling machine. A good animation can be a blinking gray-red led when it is in alarm state, a gauge that is changing value, a small alarm popup in the corner and so on... useful things anyway.
  • Pictures: use ISA symbols or schematic symbols if possible; 3D is your worst friend while representing a plant. It's important that the operator understand what's happening, not that he get fashinated.
Why gray or blue for inactive: gray means "it's all normal", is the color of the background and a color that you wouldn't pay attention. Green is the color of "go on" with semaphore, it means that a component it's running. So why to make a button green? The button will never run. Same as red for buttons: red means STOP !, DANGER! EMERGENCY SWITCH, not "finish automatic mode".
A button is a component that the operator should not pay attention at all, he just know when to push it, no need to say him "PUSH IT!". Except for Reset Alarms of course :)

I took some samples of what i think are bad screens:
Blue background with light green pipes, green and gray tanks and green valves and pumps. Definetly not a good contrast and not good pictures too.

Here pictures are better, but the contrast green on green is still bad. And on top there buttons or tag without a graphic modeling, so i can't imagine how they can help an operator.

This is what i call a useful screen.
with good contrast, not much led and the active ones in green (as you can see you notice them instantly on gray) and alarms in red.
This can be useful too, even if more complex:
Notice the good contrast for liquid levels on tank. I don't know if components are red because they are not active or in alarms (as i hope), but it's definetly a good representation.

There is a very good article about using colors, animations and setting up a Graphical User Interface; you can read it here: http://www.rollthunder.com/SoftwareThatDoesntSuck/WpfForGoodAndNotEvil.htm
Even if it's really long, i try to write his points in short:
  • First Principle: That the software that you write has zero value in and of itself. You write software for one reason and one reason only: to create value by making the user of your software happier than he would be without your software.  The only value that your software ever has or ever will have is the degree to which it increases the happiness of its users. It is extremely rare that users are willing to pay for software that decreases their overall happiness. 
  • Second Principle: That computer programs increase the happiness of users in one of two ways.  The majority of applications help a user solve a specific  problem – writing an email message or an article, buying groceries or an airplane ticket, viewing a bank statement and paying bills. The user’s only goal in using this type of program is to finish the task and get on with his life, or at least on to the next task. The faster a program converts a task from not-finished to finished, the happier the user will be.
    The second way in which a program increases a user’s happiness, less common than the first, is by putting the user into a pleasurable state that he wants to maintain as long as possible, or at least as long as it remains pleasurable, like Games.
  • Third Principle: That in neither of these cases do users want to think about the programs they are using.  At all. Ever. In the former case, they want to think about the problem they are solving: the wording of the document they are writing, or whether they have enough money to pay their bills, and which unpaid creditor would hurt them the most.  They don’t want the program to distract them from the problem they’re thinking about.  If they want to goof off and waste time, they’ll bring up Solitaire, not admire the flashing video buttons in the word processor. 
The point that i liked the most is this one: Motion attracts a user’s attention. Natural selection brutally pounded that design pattern into the human brain and visual system. Our savannah-based ancestors that noticed the twitch of the saber-tooth tiger behind the tall grass avoided being eaten and passed their attentive genes on to their descendants. The ones who didn’t notice the motion got eaten, and didn’t.  Every single user is the inheritor of roughly 13,000 generations of homo sapiens who noticed motion better than the ones who didn’t make it.
[...]
As user interface expert Jared Spool wrote of his test of a Disney web page containing an animated logo, that corporate branding icon so beloved of marketeers everywhere: “Users first tried to scroll the animation off the page, and when they couldn’t, actually covered it up with their hands so they could read the rest of the text.”

I really reccomend to check this article, is well written and with tons of examples.
And i hope you enjoyed this reading.

WPF User Controls: 7 Segment Display

7 segment displays is one of the best way to show present values in industrial programs. Operators are used to see numbers and values with  7 segment led characters, and if the operator feels comfortable with what he sees, he works better and in a more correct way.
So it's our work to make them feeling "at home" with the graphic of our programs.
To make a 7 Segment Led it's just a question of adding a custom font.
The one that i like more is NI7SEG (you can download it from here: ni7seg) or google it adding a .ttf at the end.
The code to add a Custom Font is pretty simple:

        /7SegmentLed;Component/Fonts/#NI7Seg
        
where fontfamily refers to /nameofproject;Component/font_folder/name_of_font (to be seen inside the file, not the name of the ttf file).

Then you can just create a label and apply the style:

A sample program can be found here:
http://www.mesta-automation.com/Downloads/7segmentled.rar

HMI Controls for WPF: Led (and a tutorial on WPF User Control)

You can downlaod the source code with sample here: http://www.mesta-automation.com/Downloads/Led%20Wpf.rar

Every Scada system has his own framework that contains a lot of graphic objects, from gauges to charts, that can be controlled directly by some Tags or variables.
Unfortunately .Net doesn't come with this objects, so we have to create them.
In this sample i show how to create a simple graphical Led.

Create a new Control Library (File -> New -> Project -> WPF User Control Library),
then create a new project to test the control( to test and show how to use the control).
After the creation of this 2 projects, set the test project as startup project and add as reference the  control library.
Now we are ready to start creating the graphic part.

Basically a led can be drawn as a Border object that inside it contains a color, and his background is of another color.
This is the code for the graphic part
<Grid x:Name="gridBigLed" >
        <Border x:Name="border1" BorderThickness="6" Width="{Binding ActualHeight, ElementName=gridBigLed, Mode=OneWay}" CornerRadius="{Binding ActualWidth, ElementName=gridBigLed, Mode=OneWay}">
            <Border.Background>
                <RadialGradientBrush >
                    <GradientStop Color="White"/>
                    <GradientStop x:Name="backgroundColor" Color="Red" Offset="0.835"/>
                </RadialGradientBrush>
            </Border.Background>
            <Border.BorderBrush>
                <RadialGradientBrush>
                    <GradientStop Color="#FF020202" Offset="0.383"/>
                    <GradientStop Color="#FFE4E4E4" Offset="1"/>
                </RadialGradientBrush>
            </Border.BorderBrush>
        </Border>
    </Grid>


We bind the height of the border to the height of the grid, so we can resize the control when developing our application.
Corner radius is in binding with width too, to be sure that the border will be always circular.
For the background color you can use wathever you like. I used a radial gradient with Red(Off state) and White , and i will change it with green and  white (On state) depending on the state of a property. That's why I gave the name "backgroundColor" on the red GradientStop.

To give properties to a UserControl we must use Dependency Properties.
We will give 3 properties to the user control:
- bool IsActive
- Color ColorOn (color when IsActive is true)
- Color ColorOff (color when IsActive is false)

The declaration is the following:

/// <summary>Dependency property to Get/Set the current IsActive (True/False)</summary>
        public static readonly DependencyProperty IsActiveProperty =
            DependencyProperty.Register("IsActive", typeof(bool), typeof(Led),// null);
                new PropertyMetadata(new PropertyChangedCallback(Led.IsActivePropertyChanced)));

        /// <summary>Dependency property to Get/Set Color when IsActive is true</summary>
        public static readonly DependencyProperty ColorOnProperty =
            DependencyProperty.Register("ColorOn", typeof(Color), typeof(Led), //null);
                new PropertyMetadata(Colors.Green,new PropertyChangedCallback(Led.OnColorOnPropertyChanged)));

        /// <summary>Dependency property to Get/Set Color when IsActive is false</summary>
        public static readonly DependencyProperty ColorOffProperty =
            DependencyProperty.Register("ColorOff", typeof(Color), typeof(Led),// null);
                new PropertyMetadata(Colors.Red,new PropertyChangedCallback(Led.OnColorOffPropertyChanged)));

        /// <summary>Gets/Sets Value</summary>
        public bool IsActive
        {
            get { return (bool)GetValue(IsActiveProperty); }
            set 
            {
                SetValue(IsActiveProperty, value);
            }
        }

        /// <summary>Gets/Sets Color when led is True</summary>
        public Color ColorOn
        {
            get
            {
                return (Color)GetValue(ColorOnProperty);
            }
            set
            {
                SetValue(ColorOnProperty, value);
            }
        }

        /// <summary>Gets/Sets Color when led is False</summary>
        public Color ColorOff
        {
            get
            {
                return (Color)GetValue(ColorOffProperty);
            }
            set
            {
                SetValue(ColorOffProperty, value);
            }
        }

Now there is a lot to talk about dependency properties, but basically:
you can set the starting value when you create the objects (ColorOn starts with Color.Green and ColorOff start with Color.Red)
and you should note that every property has is name written as string in the 1st field of DependencyProperty.Register method.
the properties also access to values contained in dependency properties  by getValue() and SetValue().

Every Dependency Property should have is own method when it changes. Those methods describe the behaviour of our object, basically a change of IsActive should modify the color of the border and if i change a color at runtime, depending on the state, it should refresh the color instantly.
In this case i wrote the following methods:

private static void IsActivePropertyChanced(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            Led led = (Led)d;
            if ((bool)e.NewValue)
                led.backgroundColor.Color = led.ColorOn;
            else
                led.backgroundColor.Color = led.ColorOff;
        }

        private static void OnColorOnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Led led = (Led)d;
            led.ColorOn = (Color)e.NewValue;
            if (led.IsActive)
                led.backgroundColor.Color = led.ColorOn;
            else
                led.backgroundColor.Color = led.ColorOff;
        }

        private static void OnColorOffPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Led led = (Led)d;
            led.ColorOff = (Color)e.NewValue;
            if (led.IsActive)
                led.backgroundColor.Color = led.ColorOn;
            else
                led.backgroundColor.Color = led.ColorOff;
        }

Note that every method is static and it access to the user control property by casting the dependencyobject d.

As for the constructor, i wrote a refresh depending on what color it's set.

public Led()
{
   InitializeComponent();
   if (this.IsActive)
       this.backgroundColor.Color = ColorOn;
   else
       this.backgroundColor.Color = ColorOff;       
}


In this way our control should work.

Now to test we should try it with and without databinding.
This is the test that i wrote:

<Window x:Class="LedTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:uc="clr-namespace:LedControl;assembly=LedControl"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="10"/>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <uc:Led Name="led1" Height="60" Width="60" IsActive="False" Flashing="False" FlashingPeriod="500"  />
        <TextBlock Grid.Column="1">Led without binding</TextBlock>
        <Button Name="btnChange"  Grid.Column="2"  Content="Change" Click="btnChange_Click" />
        <uc:Led Name="led2" Grid.Row="2" Height="60" Width="60" IsActive="{Binding LedStatus}"  />
        <TextBlock  Grid.Row="2" Grid.Column="1">Led with binding</TextBlock>
        <Button Name="btnChange2"  Grid.Row="2" Grid.Column="2"  Content="Change" Click="btnChange2_Click" />
    </Grid>
</Window>
         


public partial class MainWindow : Window,INotifyPropertyChanged
    {
        bool ledStatus;
        public bool LedStatus
        { get { return ledStatus; } set { ledStatus = value; this.OnPropertyChanged("LedStatus"); } }

        public MainWindow()
        {
            InitializeComponent();
            led2.DataContext = this;
            led1.ColorOn = Colors.Blue;
            led1.ColorOff = Colors.Gray;
        }

        private void btnChange_Click(object sender, RoutedEventArgs e)
        {
            led1.IsActive = !led1.IsActive;
        }

        private void btnChange2_Click(object sender, RoutedEventArgs e)
        {
            LedStatus = !LedStatus;
        }


        #region INotifyPropertyChanged members

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }

        #endregion  

The 1st button test the led by changing the color from codebehind, the second test it in binding with a property contained (in this case) in the mainwindow directly.

Playing with Blend and adding more Dependency Properties will give even a better result.

Sample App is here: http://www.mesta-automation.com/Downloads/Led%20Wpf.rar

HMI Controls for WPF: Gauge

[Check the updated post here: http://www.mesta-automation.com/wpf-gauge-with-samples/]

Most of times the Gauge indicator is used in HMI projects to visualize Speed - Pressure - Temperatures and so on.
I also prefere using Gause against other tipes of controls such as thermometers, bar graph and others, becuase the measure it's clear and the minimum, maximum and alarm threshold are evidents.
In WPF there are 2 kind of free gauges with free source code:
1) http://wpfgauge.codeplex.com/


this is a free gauge that has no animations (and it can be good ) but it's under the LGPL license, so this means that the code using this gauge must be GPL - licensed.

2) http://www.codeproject.com/KB/silverlight/circulargaugecontrol.aspx?msg=3745697#xx3745697xx
This one is the one that i prefere. It's BSD License (so you can use it basically everywhere) and it is for both Silverlight and WPF.
It's not autosizing and that's a pity, and to dimension it you have to play with some controls.
But anyway it's a great control with a threshold indicator and easy parameters to play around.
It's easy to change colors and sizes of scale and numbers, so it can become a manomether, a thermometer and a tachimeter depending on what application you are working on.

The project can be downloaded from the original site or here:

http://www.megaupload.com/?d=5TMUYC9A


WPF Control: Listbox of checkbox with Search google-like

One thing that i like of WPF is the possibility of making easy-to-use controls to manage data.
A control that i use a lot of times to filter dataviews, charts, get queryes parameters and so on is a listbox of checkbox.
This isn't that special, but with ICollectionView and the possibility of having a fast way to filter results like the search box in google.com it become a really powerful tool.

I invite you to download the demo (link at the bottom of this page) to understand better.

Let's start from an example:
I have an observable collection of "Fruits", objects that contain a property "Name" and a property "Show" that indicates if the object has to be visualized or filtered.

To filter this collection i can use the ICollectionView, that permits to filter a collection and has a method Refresh() that reload the collection with the filter parameters.

So in the properties i add:
 class MyFruitCollection : ObservableCollection
    {

private ICollectionView filteredCollection;
public ICollectionView FilteredCollection { get { return filteredCollection; } }


and the filter string:

private string filter = "";
        public string Filter
        {
            get { return this.filter.ToUpperInvariant(); }
            set
            {
                if (this.filter != value)
                {
                    this.filter = value;
                    this.filteredCollection.Refresh(); //
Notice that i call Refresh() at every change of filter
                }
            }
        }


In the constructor of my collection i add some fruits(just for example) and i load the ICollectionView datasource:

        public MyFruitCollection()
        {
            this.Add(new MyFruit("Orange"));
            ...
            this.Add(new MyFruit("Watermelon"));

            this.filteredCollection = CollectionViewSource.GetDefaultView(this);
            this.filteredCollection.Filter = ContainsFilter;
        }

Then i set the filters on this method:

private bool ContainsFilter(object item)
        {
            var fruit = item as MyFruit;
            if (fruit == null)  //check if fruit is null
            {
                return false;
            }
            if (string.IsNullOrEmpty(this.Filter)) //check if search box is empty or null
            {
                return true; //show all items if there is no text in the search textbox
            }
            if (fruit.Name.ToUpperInvariant().Contains(this.Filter))
//checks if fruit.name contains the search text
            {
                return true;
            }
            return false; //if it doesn't contain anything don't show the item
        }


 Xaml is pretty simple, as usual it's all about databinding:

And this is the code behind:

    public partial class MainWindow : Window
    {

MyFruitCollection fruitCollection = new MyFruitCollection();

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = fruitCollection;
//notice that all the application is in binding
        }

...
}

The resul is pretty cool and it makes apps a lot more confortable, just try yourself :)
Download the example here:
http://mesta-automation.com/Downloads/Selection%20control.rar

A good (free) set of 240 icons

A big problem and a big waste of time for a programmer is the research of icons and images to associate to buttons, panels, toolbars and so on.
I really hated to do that with Google image-finder, so i searched a lot until i found a site that contained a million of icons.
Of course it can't exist that for every program i search in a database containing so many designs, so i want to show you a set of icons that in my opinion cover almost all that a programmer needs.
As usual remember that an icon should HELP the operator, not just be pretty. If you feel that the icon is not so meaningful, it's better to remove it and just leave text on the button (so the operator is forced to read it).
This is a small (and almost useless) preview of the set, that contains more useful icons for sure:

But i invite you to visit this page: http://www.iconarchive.com/category/application/aesthetica-2-icons-by-dryicons.html to see the complete set (that is really big, around 240 icons).
I want to point the attention on some icons:
- Accept, Add, Remove and Edit are pretty straightforward. I think that no one can do confusion with this set of icons.
- Back, Next, Down and Top are pretty useful too, even if i don't like to abuse of them because they are not always understandable if the context is not well defined.
- Info, Help, Search and Warning are awesome. It's impossible to don't understand what they means and they are similar to windows ones too.
- Lock - Unlock icons for password login is always useful.
- Charts, Folders, Databases, Home, Word and Calendar got always a use in programs, and they are included too.

The rest is quite trashy, or not so useful, but it always depends on what you are doing.
I really invite you to check out this set, downloadable from the bottom of this page:
http://www.iconarchive.com/category/application/aesthetica-2-icons-by-dryicons.html
selecting Linux (.png) files included (so you get the version with the set of 16x16 - 32x32 - 48x48 - 64x64 - 128x128 pixels)
Remember that if you use them you should read carefully the license, that permit a free use of this set, and to respect the work of this guys.

WPF and OPC: a full sample project with RSLinx and databinding

Now that i wrote about databinding, pages and so on, i publish an example on how to connect real time values readed from a PLC (in this case an Allen Bradley PLC, but it can be anyone), update an object collection with this values, and then display them on different pages.

As usual i have my 2 tanks and i want to read what liquid is inside every tank (defined as 16bit integer).
1st tank word is N7:0, second is N7:1
For each tank there is a button that changes its content(writing the PLC word).

This is the new code to analyze: i have 2 buttons that writes the words on PLC, then i have the callback where i read values in PLC, cast them and update my objects.
This objects are defined in the OPC Client class and they are defined as "public"  because i want to access their properties from every window that needs to display real time values or to control them.


This is the MainWindow, where the program begin and where i create the opcclient object as static.
To access to it's properties i just need to bind UI items by databinding.




To access the properties of objects in another window or page, i do like in this example.

And this is the final result

This is how the setup for PLC OPC Server, that should be called as [UNTITLED_2]


Hope it's helpful.
Full solution here:

http://www.mesta-automation.com/Downloads/opc%20sample%202.rar

Previus post describe more in details what's used in this example, if you're interested.

Databinding #3: binding directly to a Property with INotifyPropertyChanged

Hi,
this is the last part about databinding.
You can find the 1st part here and the 2nd part here
We saw how to bind UI controls on UI elements and on elements that belongs to a collection.
We noticed also that when an observable collection changes(if one item get added or removed), is changes also the UI elements in bind with the collection; the limit of observable collection is that if i change a property in a element inside it, it doesn't update it.
To do this update of property inside elements of a collection, we need to implement an interface, called INotifyPropertyChanged, that fires an event when the property changes, updating all the elements that are in bind with it.

Let's analyse an example:
i 2 tanks, and i have a collection of 2 liquid (liquid[0] and liquid[1]).
Liquid[0] is the content inside the 1st tank, liquid[1] is the content inside the 2nd tank.
I want to change the color (or state) of content changing the property inside the class, and i want that the UI updates the color when it changes of course.
Let's write the new class for the content:


class Liquid:System.ComponentModel.INotifyPropertyChanged
{
public string Name { get; private set; }

private SolidColorBrush liquidColor;
public SolidColorBrush LiquidColor { 
get
{
return liquidColor;
}
private set 
{ 
liquidColor = value; 
this.OnPropertyChanged("LiquidColor");
}
}

public Liquid(string name, Color color) 
{
this.Name = name;
this.LiquidColor = new SolidColorBrush(color);            
}

public void Change(SolidColorBrush newColor) 
{
this.LiquidColor = newColor; 
}

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}

This is the implementation if INotifyPropertyChanged.
In the bottom part there is the definition of the event that i throw, and inside the declaration of the property LiquidColor i throw the event every time that this the property changes.
Then i added a method Change, that changes the color with a new one.

Let's define a liquid collection:
class LiquidCollection:ObservableCollection

{

public LiquidCollection() 

{ 

this.Add(new Liquid("Liquid Silos 1", Colors.Aqua));

this.Add(new Liquid("Liquid Silos 2", Colors.Orange));

}

}


Datacontest:
public MainWindow()

{

InitializeComponent();



LiquidCollection liquids = new LiquidCollection();

ellipseSilos1.DataContext = liquids[0];

ellipseSilos2.DataContext = liquids[1];

}


and 2 button's callbacks that change colors to each silos:
private void btnChangeS1_Click(object sender, RoutedEventArgs e)

{

((Liquid)ellipseSilos1.DataContext).Change(colors[i]);

if (i < 10) i++; else i = 0;

}



private void btnChangeS2_Click(object sender, RoutedEventArgs e)

{

((Liquid)ellipseSilos2.DataContext).Change(colors[i]);

if (i < 10) i++; else i = 0;

}


UI Databinding now refers directly to the property that changes:

And we have the UI update when property changes inside the collection.



As usual the complete solution can be found here: 
http://www.mesta-automation.com/Downloads/Databinding3.rar

Next post i'll make a simple project in wpf where i connect an opc server to the UI through databinding.

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

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