Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Hosting an Electronic Form with a Windows Form

3.40/5 (7 votes)
21 Nov 2009CPOL3 min read 34.6K   411  
An article that explains how a Windows Form can host an electronic form.

Introduction

Windows Forms applications can be effective in hosting electronic forms. Microsoft Office InfoPath was developed with Microsoft Office 2003, and is now an integral part of the Microsoft Office System. Its user interface is relatively straightforward, where the form designer usually picks a Layout “Table with a Title” in order to contain tables within that outer table. This establishes the look and feel. Then, controls can be dragged and dropped onto the surface. Below is a very basic example of a form:

Capture.JPG

The first part added was a “Table with a Title”. Directly underneath, where sample text lay, I placed a section object. As the cursor blinked on that section, I went back to layout and chose “custom table”, where I inserted five columns and three rows. And so on. The purpose of this article is to explain how an electronic form can be loaded onto a Windows Form interface. I will assume that the reader has a downloaded and workable copy of Visual Studio 2008 SP 1, and that the user downloads a trial copy of InfoPath 2007. It is well worth the time spent. The form that will be loaded in our example is a downloaded Status Report form.

It should be clear that the form will be embedded in the Windows Form, and that the Windows Form will host the InfoPath 2007 application. To host an InfoPath Form in a Windows application, you have to use the InfoPath FormContent control. So, the first thing to do is fire up InfoPath 2007 and either use one of the templates or create a simple form similar to that of the above. Save that form and publish it to a network location, say, c:\temp\Status.xsn. Finish the publishing wizard and close InfoPath.

Now, fire up Visual Studio 2008 and create a Windows Forms application in C#. Right-click the toolbox and select “Choose items”. Browse to the %program files\Microsoft Office\Office 12 directory. Find Microsoft.Office.InfoPath.FormControl.dll and double-click it. Click OK in the Choose Toolbox Items dialog. Drag the FormControl control to the Windows Form. Underneath the FormControl, drag and drop a button, which will call “Load Form”, a label,, which we’ll call “Load From”, and a text box control underneath the label.

Now the easiest part to get out of the way is the button event handler. So we double-click the button, Load Form, and insert the event handler:

C#
formControl1.NewFromFormTemplate(@"c:\temp\status.xsn");

Now you’ll wire the form to accept the Submit event from the embedded form. Add the following after the partial class declaration to add the interface to your form:

C#
Microsoft.Office.Interop.InfoPath.ISubmitToHostEventHandler

This interface declaration comes right after the Form. Right-click it and select “Implement interface”. Here is the entire file:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Xml;
using System.Xml.XPath;
using Microsoft.Office.InfoPath;
using System.Text;
using System.Windows.Forms;

namespace EmbeddedForm
{
    public partial class Form1 : Form, 
           Microsoft.Office.Interop.InfoPath.ISubmitToHostEventHandler
    {
        public Form1()
        {
            InitializeComponent();
        }

        
        private void button1_Click(object sender, EventArgs e)
        {
            formControl1.NewFromFormTemplate(@"c:\temp\status.xsn");
        }

        #region ISubmitToHostEventHandler Members

        public int SubmitToHostEventHandler(object sender, 
                   string adapterName, out string errorMessage)
        {
           XPathNavigator xnav= formControl1.XmlForm.MainDataSource.CreateNavigator();
           xnav = xnav.SelectSingleNode("/my:myFields/my:SomeOtherValue", 
                                        formControl1.XmlForm.NamespaceManager);
           textBox1.Text = xnav.InnerXml;
           errorMessage = "";
           return 1;
        }

        #endregion

        private void Form1_Load(object sender, EventArgs e)
        {
            formControl1.SetSubmitToHostEventHandler(this);
        }
    }
}

Notice that I imported other namespaces, like the XML namespace and the InfoPath namespace. InfoPath is XML-centric. Here is the Designer form code:

C#
namespace EmbeddedForm
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources
        ///      should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = 
                new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.formControl1 = new Microsoft.Office.InfoPath.FormControl();
            this.button1 = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.formControl1)).BeginInit();
            this.SuspendLayout();
            // 
            // formControl1
            // 
            this.formControl1.Enabled = true;
            this.formControl1.Location = new System.Drawing.Point(12, 33);
            this.formControl1.Name = "formControl1";
            this.formControl1.OcxState = ((System.Windows.Forms.AxHost.State)
                (resources.GetObject("formControl1.OcxState")));
            this.formControl1.Size = new System.Drawing.Size(558, 434);
            this.formControl1.TabIndex = 0;
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(56, 500);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 1;
            this.button1.Text = "Load Form";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(365, 485);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(57, 13);
            this.label1.TabIndex = 2;
            this.label1.Text = "Load From";
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(321, 516);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 3;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(595, 548);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.formControl1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.formControl1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private Microsoft.Office.InfoPath.FormControl formControl1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

We now build the solution, and then type the path to the InfoPath 2007 form: @"C:\temp\status.xsn".

1.JPG

When downloading the zip files, extract them into a named Projects folder. If you don’t use the “Status Report” form, then remember to change the path parameter in the source code. Make a temp folder after you download InfoPath 2007, and place one of the sample forms in that temp subfolder. InfoPath form files have a .xsn file extension.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)