Posts Tagged ‘WPF & XAML’

DependencyProperties for zenon WPF controls

Wednesday, September 28th, 2011

Introduction:

When you begin to develop WPF controls for zenon, you will soon stumble across DependencyProperties. What are dependency properties? The quick definition from the MSDN documentation says that a dependency property is a "property that is backed by the WPF property system." They are quite similar to normal .NET properties, but the concept behind DependencyProperties is much more

online pharmacy

complex and powerful. It gives you a bunch of infrastructure to do all things you often want to do with a normal property: validate it, coerce it into a proper range, give out change notifications and a number of other aspects. A normal .NET property is read directly from a private member in your class, whereas the value of a DependencyProperty is resolved dynamically when calling the GetValue() method that is inherited from DependencyObject.

Advantages of DependencyProperties:

  • Reduce memory footprint
  • Value inheritance
  • Change notification
  • Value validation

How to create a DependencyProperty:

To create a DependencyProperty, you have simply to add a static field of type DepdencyProperty to your type and call DependencyProperty.Register() to create an instance of a dependency property. The naming convention of DependencyProperties fields is important. The name of the fields is always the name of the property, with the suffix Property appended. To make it accessible like a normal .NET property you need to append a property wrapper. This wrapper does nothing else than internally getting and setting the value by using the GetValue() and SetValue()

usa pharmacy

Methods inherited from DependencyObject and passing the DependencyProperty as key. HINT: If you are using Visual Studio, you can type propdp and hit 2x TAB to create a dependency property.

// Dependency Property
public static readonly DependencyProperty LastNameProperty =
     DependencyProperty.Register( "LastName", typeof(String),
     typeof(MyControl));
 
// .NET Property wrapper
public String LastName
{
    get { return (String)GetValue(LastNameProperty); }
    set { SetValue(LastNameProperty, value); }
}

Each DependencyProperty provides callbacks for change notification, value coercion and validation. These callbacks are easily registered on the dependency property with

cheap generic cialis

FrameworkPropertyMetadata.

// FrameworkPropertyMetadata
new FrameworkPropertyMetadata( "zenon",
    OnCurrentTimePropertyChanged,  
    OnCoerceCurrentTimeProperty,
    OnValidateCurrentTimeProperty);

Pie Chart #2: Expanding the ChartControllibrary to enable access to the zenon-API.

Thursday, June 24th, 2010

The previous post described how to create an own WPF Pie-Chart component using Microsoft Expression Blend. The ChartControl is a rather simple control with limited functionality. And the fact that we can pass datasets to it by use of “string” and “double” properties is actually sufficient for its purpose. But for more complex WPF-Controls the usage of simple data type properties might not be enough. Imagine a WPF-Control which displays a Pie-Chart showing the amount of active alarms in certain areas, and an additional List displaying the current active alarms of the area which is selected in the Pie-Chart. This behavior could of course be implemented by “normal” data type properties and coding in the WPF-Control combined with coding in VBA. But it would require rather large amount of coding on both zenon and WPF-side; causing the entire solution to be become complex and simply put: Virtually impossible to re-use on different screens. In this case it would be best if we could keep all the coding on WPF-side, and create a compact Control with full access to the zenon-API. To show how easy it is to pass objects from the zenon-API on to a WPF Control, this post will explain how the ChartControlLibrary can be expanded to do this and get full access of the zenon-API. This post will be using the solution which was created by the previous post “Pie-Chart#1”.

Reference to the zenon-API

In order to use the object model from the programming interface in a WPF-Control, a reference to the COM-Object model has to be added to the project. Unfortunately the 

user interface from Blend only supports adding references to .Net assemblies, which zenon is not. This is a user interface limitation only, once a reference to a registered COM-Object is available in the project file we can continue to work with Blend. So we could modify the “ChartControlLibrary.csproj” file by use of a text editor and add the reference by hand. Or we could open the solution with an editor that supports an easy way of adding COM-References, and a reference from the “COM”-Tab to the zenon programming interface. Microsoft Visual C# 2010 Express supports this and can be downloaded for free from the Microsoft homepage. To manually add the reference to the csproj file, open it in notepad and add the following ItemGroup-Entry:

<ItemGroup>

  <COMReferenceInclude=stdole>

    <Guid>{00020430-0000-0000-C000-000000000046}</Guid>

    <VersionMajor>2</VersionMajor>

    <VersionMinor>0</VersionMinor>

    <Lcid>0</Lcid>

    <WrapperTool>primary</WrapperTool>

    <Isolated>False</Isolated>

  </COMReference>

  <COMReferenceInclude=zenOn>

    <Guid>{6F9DE1F1-A404-11CF-95D0-0020D58000EC}</Guid>

    <VersionMajor>1</VersionMajor>

    <VersionMinor>0</VersionMinor>

    <Lcid>0</Lcid>

    <WrapperTool>tlbimp</WrapperTool>

    <Isolated>False</Isolated>

  </COMReference>

</ItemGroup>

right before the line:

<ImportProject=$(MSBuildToolsPath)\Microsoft.CSharp.targets />

After saving the project file we can open the solution file in Microsoft expression Blend, and we will notice 2 new entries (stdole.dll and zenOn) in the reference node. From now on we can use the objects from the programming interface.

Expanding the ChartControl

In the previous post, adding variable values to the ChartControl was done by using 3 properties. Let’s simplify this process and the VBA-code by passing an entire variable-object on to the WPF-Control. We will do this by implementing a new property “AddVariableToChart” to the public properties region. This property (type Object) can be called from VBA, and requires a zenon.Variable object.

#region API Access Properties

///<summary>

/// The “AddVariableToChart” property, which is more or less used as a method.

/// We assume that the value passed to this property is a zenon.Variable,

/// check if it’s online and if so, add it to the chartdata.

/// NOTE:Setting anything different than a zenon.Variable onto this property will probably crash the Control.

///</summary>

public Object AddVariableToChart

{

  get

  {

    return null;

  }

  set

  {

    if (value != null)

    {

      zenOn.Variable obVar = (zenOn.Variable)value;

      if (obVar.IsOnline())

      {

        AddValueToChart(obVar.Name,(double)obVar.get_Value(0));

        //Everytime a variable has been added we change the title of the pie.

        string strTitle;

        //Access the languagetable to retrieve the ChartTitle-Text in the correct language.

        strTitle=obVar.Parent.Parent.String(@”@ChartTitle”);

        strTitle = strTitle + m_Data.Length.ToString();

        ChartTitle=strTitle;

      }

    }

  }

}

#endregion

 

Additionally we add a few simple properties to clear the chart data, and 2 more to set the chart and legend title:

///<summary>

/// Get/Set the Title for the Pie-Chart.

///</summary>

public String ChartTitle

{

  get

  {

    return chart.Title.ToString();

  }

  set

  {

    chart.Title = value;

  }

}

///<summary>

/// Get/Set the Title for the Pie-Legend

///</summary>

public String LegendTitle

{

  get

  {

    return chart.LegendTitle.ToString();

  }

  set

  {

    chart.LegendTitle = value;

  }

}

///<summary>

/// A fake “clear” property which clear the Chartdata when called.

///</summary>

public Boolean Clear

{

  get

  {

    return false;

  }

  set

  {

    //Wipe existing chartdata, and update the chart.

    m_Data = null;

    chart.DataContext = m_Data;

    chart.UpdateLayout();

  }

}

When the “AddVariableToChart” property is set (from VBA) the WPF-Control takes the variable and checks whether it is online. If it is, it will get the current value and add it together with the variable name to the chart data. Additionally the variable object is used to “walk” back up the object tree and use the “String” method from the zenon project to translate a text which is used for the chart title (assuming an entry in the language table is present). If we compile the solution and use the zenon-Project from the

cheapest cialis

previous post (replacing the ChartControlLibrary.dll of course”, the following VBA code would lead to the same result as the previous post with the addition of a chart title.

Public Sub PassDataAsVariableByObjects()

    Dim obElement As Element

    obElement = thisProject.DynPictures.Item(0).Elements.Item(“WPF-Element_1”)

    obElement.WPFProperty(“Chart1”, “Clear”) = True

    obElement.WPFProperty(“Chart1”, “AddVariableToChart”) = thisProject.Variables.Item(“internal variable1”)

    obElement.WPFProperty(“Chart1”, “AddVariableToChart”) = thisProject.Variables.Item(“internal variable2”)

    obElement.WPFProperty(“Chart1”, “AddVariableToChart”) = thisProject.Variables.Item(“internal variable3”)

    obElement.WPFProperty(“Chart1”, “AddVariableToChart”) = thisProject.Variables.Item(“internal variable4”)

End Sub

Just like the WPF-Control used the language table method (Project.String) to translate a string entry, it could use the zenon-API to create its own OnlineContainers, execute functions, react to Alarm/Cel Events, etc. All what’s required is an Object-Property which is called from VBA to pass a zenon-object through to the Control-Context and guarantee access to the API.

Note that the usage of references to API-Objects in WPF-Control context requires a thread safe implementation, and event handlers for project events (active, inactive, prereload and postreload) to ensure that references stored on WPF-side are a released in a correct way.

Files for this post

Source files for this post. Compiled assemblies.

System requirements:

  • Solution from the previous post “Pie-Chart#1”
  • zenon 6.51 or higher
  • WPF-Requirements as stated in the zenon documentation.
  • WPF-Toolkit:  (available from http://wpf.codeplex.com/ as a part of the Microsoft Shared Source Initiative).
  • Microsoft Expression Blend 3 or higher (only required for viewing and compiling the source solution).

Pie Chart#1:Using the WPF element combined with additional assemblies.

Tuesday, June 22nd, 2010

As described in the previous post, nearly all WPF-functionality can be used in zenon. And depending on the functional requirements, programming knowledge might be required on user side. The goal of this post is to show how “easy” it is to create an own WPF-Control when more complex functionality is required. And how this WPF-Control, using an additional existing (in this case Microsoft) WPF-Assembly, can be used in zenon by use of the WPF-Element and Loose XAML.

Required: Let’s assume we want to display the values of 4 process variables (which could for example represent the amount of active alarms in 4 different alarm areas) in a bit of nicer way than just a bunch of numeric values. On demand (for example on function execution) we would like them, a description and their ratio to be displayed in a Pie-Styled Chart.

Solution: (more…)

zenon & Windows Presentation Foundation

Wednesday, June 16th, 2010

With the addition of Windows Presentation Foundation to the .Net framework, Microsoft introduced a new Toolkit to both create and use more sophisticated and modern user interfaces. Built on DirectX, WPF offers us various graphical technologies in addition to a large set of controls. The available technologies range from a fairly easy level (gradient, transparency and transformation effects) up to a more advanced level (“flash”-style storyboards, Viewports, access to the entire .Net Framework).

Extensible Application Markup Language (XAML)

The base of each WPF-user interface is an XAML file. XAML documents are files which describe the visual parts of a user interface. An XAML file can be seen as an extended version of the well known XML-file format, using a somewhat special namespace. Just like XML also XAML files can be opened and edited in any Text-Editor, but using better graphical editors like Microsoft Expression Blend is advised. Each and every element inside a XAML document maps to an instance of a .Net Class or Object. And each of the XAML-attributes maps to a property or event of these classes or object instances. (more…)