You develop Microsoft Dynamics NAV Windows client control add-ins using the API that is defined in the Microsoft.Dynamics.Framework.UI.Extensibility assembly. A control add-in is defined as a class in a Visual C# solution. You can include more than one control add-in a single solution. When you have finished developing a control add-in, you build and sign an assembly before you install it on the computer that is running the Microsoft Dynamics NAV Windows client.

To create a control add-in, you need the following prerequisites:

To create the Microsoft Dynamics NAV Windows client control add-in

  1. In Visual Studio, create a Visual C# project type by using the Class Library template.

  2. In the project, add references to the following assemblies:

    • Microsoft.Dynamics.Framework.UI.Extensibility.dll assembly
      By default, the path of the assembly is C:\Program Files\Microsoft Dynamics NAV\90\RoleTailored Client. This reference is required for all control add-ins.
    • System.Windows.Forms
      Contains classes for creating user interfaces for Windows-based applications.

    Add additional references as required.

  3. Open the class.cs file and add the following using directives.

    C# Copy Code
    using Microsoft.Dynamics.Framework.UI.Extensibility;
    using Microsoft.Dynamics.Framework.UI.Extensibility.WinForms;
    using System.Windows.Forms;

    Add additional references as required.

  4. Declare a class for the control add-in that uses the Microsoft.Dynamics.Framework.UI.Extensibility.ControlAddInExportAttribute attribute. Derive the class from an abstract base class and implement the control add-in definition interface, as shown in the following examples.

    C# Copy Code
    [ControlAddInExport("MyCompany.MyProduct.MyAddin")]
    public class MyFieldPopupAddin : WinFormsControlAddInBase, IObjectControlAddInDefinition

    C# Copy Code
    [ControlAddInExport("MyCompany.MyProduct.MyAddin")]
    public class MyFieldPopupAddin : StringControlAddInBase

    For information about the base classes and interfaces, see Client Extensibility API Overview.

    The Microsoft.Dynamics.Framework.UI.Extensibility.ControlAddInExportAttribute attribute declares the class in the assembly to be a control add-in that is identified by its Microsoft.Dynamics.Framework.UI.Extensibility.ControlAddInExportAttribute.Name property, which in this case is MyCompany.MyProduct.MyAddin in C#. Because an assembly can contain more than one control add-in, the Microsoft Dynamics NAV Windows client uses the Microsoft.Dynamics.Framework.UI.Extensibility.ControlAddInExportAttribute attribute to differentiate each control add-in that is found in an assembly. The Microsoft.Dynamics.Framework.UI.Extensibility.ControlAddInExportAttribute.Name is used to register the control add-in in Microsoft Dynamics NAV Server.

    Tip
    If you give the control add-in the same name as the assembly, then you do not have to install the assembly on the client computer. In this case, you only install the assembly on the computer that is running Microsoft Dynamics NAV Server. When a client requests the control add-in, Microsoft Dynamics NAV Server will automatically deploy the assembly to the client.

    For more information, see How to: Register a Windows Client Control Add-in.

  5. Implement the abstract base method Microsoft.Dynamics.Framework.UI.Extensibility.WinForms.WinFormsControlAddInBase.CreateControl and add code that defines the control add-in.

    C# Copy Code
    protected override Control CreateControl()
           {
               /// Include control add-in code here.
           }
  6. Add code to override additional base class members as required for your control add-in.

    For example, a field control on a Microsoft Dynamics NAV Windows client can have a caption. If you do not want a caption, then override the Microsoft.Dynamics.Framework.UI.Extensibility.WinForms.WinFormsControlAddInBase.AllowCaptionControl property and return false (the default value is true).

    C# Copy Code
    public override bool AllowCaptionControl
    {
    get 
    { 
     return false;
    }

    The caption will span the caption column and the data column of the page.

  7. To bind the control add-in to data in the Microsoft Dynamics NAV database, add the following code that gets or sets the Microsoft.Dynamics.Framework.UI.Extensibility.IValueControlAddInDefinition.Value property.

    C# Copy Code
    /// Gets a value indicating whether the Value property has
    /// changed its value.
    public bool HasValueChanged { get; set; }
    /// Gets or sets the Value Property.
    public object Value
    {
        get
        {
            // Include value handling code here.
            return null;
        }
        set
        {
            // Include value handling code here.
            
        }
    }
    
    Note
    The Microsoft.Dynamics.Framework.UI.Extensibility.WinForms.StringControlAddInBase class already overrides the Microsoft.Dynamics.Framework.UI.Extensibility.IValueControlAddInDefinition.Value property to transfer data between the control add-in and the Microsoft Dynamics NAV database.

    For more information, see Binding a Windows Client Control Add-in to the Database.

  8. To define events that call the OnControlAddin C/AL trigger of a page field control, add the following C# code to declare an event handler.

    C# Copy Code
       public event ControlAddInEventHandler ControlAddIn;

    Add code to raise the event where appropriate.

    For more information, see Exposing Events and Calling Respective C/AL Triggers from a Windows Client Control Add-in.

  9. To add an event that will be represented by a new trigger in C/AL code of a Microsoft Dynamics NAV page object, use the managed attribute ApplicationVisibleAttribute and add code for C# methods and properties.

    C# Copy Code
    [ApplicationVisible]
         public void DrillDown(int nodeId)
         {
          …
         }
         public int SelectedNode
         {
          get {…}
          set {…}
         }    
    

    The methods and properties must be public. For more information, see Exposing Methods and Properties in a Windows Client Control Add-in.

  10. To add a method or property that can be called from the C/AL code of a Microsoft Dynamics NAV page object, use the managed attribute ApplicationVisibleAttribute and add code for C# methods and properties.

    C# Copy Code
    /// <summary>
    /// Event will be fired when the AddIn is ready for communication through its API
    /// </summary>
    [ApplicationVisible]
    public event MethodInvoker AddInReady;
    

    The methods and properties must be public. For more information, see Exposing Methods and Properties in a Windows Client Control Add-in.

  11. Build and sign the solution.

Signing an Assembly That Contains a Control Add-in

To use an assembly that contains a control add-in with the Microsoft Dynamics NAV Windows client, it must be signed. Signing gives the assembly a public token key, which is a unique identity that is used to make sure that the control add-in runs code from a trusted assembly. When you register a control add-in in Microsoft Dynamics NAV Server, you provide the public token key. At run time, the Microsoft Dynamics NAV Windows client uses the public token key to load the appropriate control add-in.

Assemblies are signed with a key file that contains the public key token and an optional password. You can sign an assembly that contains a control add-in by creating a new key file or using an existing one. For more information about how to sign assemblies, see How to: Sign Assemblies and Strong-Name Signing for Managed Applications.

To sign the Microsoft Dynamics NAV Windows client add-in assembly

  1. Open the project's properties.

  2. On the Properties window, choose the Signing tab.

  3. Select the Sign the assembly check box.

  4. In the Choose a strong name key file box, select New to create a new key file or Browse to use an existing key file.

  5. Choose the OK button.

For information about how to determine the public token key, see How to: Determine the Public Key Token of the Windows Client Control Add-in and .NET Framework Assembly.

Example

The following code illustrates a control add-in that implements the Microsoft digital ink control on a Microsoft Dynamics NAV Windows client page field. For example, you could use this control add-in on a sales order page to allow customers to sign their sales orders with a tablet PC. The control add-in is designed to bind with a table field in the Microsoft Dynamics NAV database to store and retrieve signatures. Because the signatures are transferred as binary data, the example implements the Microsoft.Dynamics.Framework.UI.Extensibility.IObjectControlAddInDefinition interface.

C# Copy Code
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Ink;
using System.Drawing;
using Microsoft.Dynamics.Framework.UI.Extensibility;
using Microsoft.Dynamics.Framework.UI.Extensibility.WinForms;
using System.Windows.Forms;
namespace NavInkControl
{
    [ControlAddInExport("MyCompany.MyProduct.MyNavInkControlAddin")]
    public class NavInkContol : WinFormsControlAddInBase, IObjectControlAddInDefinition
    {
        InkPicture _inkControl;
        private bool _loaded = false;
        /// Creates the control for displaying and adding signatures.
        protected override Control CreateControl()
        {
            _inkControl = new InkPicture();
            _inkControl.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            _inkControl.MinimumSize = new Size(40, 50);
            _inkControl.MaximumSize = new Size(Int16.MaxValue, 100);
            return _inkControl;            
        }
        #region IObjectControlAddInDefinition Members
        public event ControlAddInEventHandler ControlAddIn;
        /// Gets a value indicating whether the Value property instance has changed. true if this instance has changed its value; otherwise, false.
        public bool HasValueChanged
        {
            get { return _inkControl.Ink.Dirty; }
        }
        /// Gets or sets the value.
        public object Value
        {
            get
            {
                return this._inkControl.Ink.Save();
            }
            set
            {
                if (value is byte[])
                {
                    byte[] data = (byte[])value;
                /// Specifies that the data loads only once so that data cannot load while the user is drawing.
                    if (data != null && !this._loaded)
                    {
                        this._inkControl.Ink.Load(data);
                        this._loaded = true;
                    }
                }
            }
        }
        #endregion
    }

See Also