次の方法で共有


InfoPath 2003 オブジェクト モデルを使用してイベント ハンドラを追加する方法

InfoPath 2003 オブジェクト モデルと互換性のあるフォーム テンプレート プロジェクトでイベント ハンドラ関数を追加するメニュー コマンドは、スクリプトを使用する場合と基本的に同じです。たとえば、OnLoad イベント ハンドラを追加するには、InfoPath のデザイン モードでフォームを開いているときに、[ツール] メニューの [プログラミング] をポイントし、[Loading イベント] をクリックします。Microsoft Visual Studio Tools for Applications (VSTA) または Microsoft Visual Studio コード エディタの OnLoad イベント ハンドラのフォーム コードに自動的にフォーカスが切り替わります。

マネージ コードのフォーム テンプレート プロジェクトでは、イベント ハンドラ関数を含むクラスとイベント ハンドラ自体が、コード モジュール内で InfoPath に固有の属性によって識別されます。

以下のすべての手順では、Microsoft Office InfoPath 2007 (Microsoft Visual Studio Tools for Applications (VSTA) インストール済み)、Visual Studio 2005 (Microsoft Visual Studio 2005 Tools for the 2007 Microsoft Office System インストール済み)、または Visual Studio 2008 と Visual Studio Tools for Office でフォーム テンプレート プロジェクトを開いているものと仮定します。

コマンド ボタンの OnClick イベントに対するイベント ハンドラを追加する

  1. [コントロール] 作業ウィンドウまたは Visual Studio の [ツールボックス] で、[ボタン] をクリックしてフォームにボタンを追加します。

  2. ボタンをダブルクリックし、[フォームのコードを編集] をクリックします。

    コード エディタの OnClick イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

フィールドまたはグループの OnBeforeChange、OnValidate、または OnAfterChange イベントに対するイベント ハンドラを追加する

  1. たとえば [テキスト ボックス] コントロールなど、フィールドまたはグループにバインドされたデータ入力コントロールを右クリックします。

  2. [プログラミング] をポイントし、[OnValidate イベント] をクリックします。

    コード エディタの OnBeforeChangeOnValidate、または OnAfterChange イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

    メモメモ :

    Visual Studio を使用している場合、フィールドまたはグループにイベント ハンドラを追加した後で、InfoPath の [データ ソース] 作業ウィンドウでデータ ソースのスキーマにそのフィールドまたはグループに影響するような変更 (たとえば、名前の変更や移動など) を行うと、Visual Studio に戻ったときに、"フォーム テンプレートのスキーマに変更を加えたため、フォームのコード内の XPath 式を更新する必要があります。これらの式を自動的に更新しますか?" というようなメッセージが表示されます。イベント ハンドラをフィールドまたはグループと関連付けるために使用する XPath 式に変更が自動的に反映されるように、必ず [はい] をクリックしてください。[いいえ] をクリックした場合は、イベント ハンドラが正しく実行されるように、イベント ハンドラの InfoPathEventHandler 属性の MatchPath パラメータで XPath 式を手動で更新する必要があります。詳細については、このトピックの後で説明する「イベント ハンドラの識別方法」を参照してください。

    メモメモ :

    InfoPath の [データ ソース] 作業ウィンドウでスキーマに変更を加えると、Visual Studio に戻ったときにこれらの変更が確認なしで自動的に保存され、既存のフォーム テンプレートに上書きされる点にも注意してください。

フォームの OnLoad、OnSwitchView、OnContextChange、または OnSign イベントに対するイベント ハンドラを追加する

  • [ツール] メニューの [プログラミング] をポイントし、イベント ハンドラを作成するフォーム イベントをクリックします。

    コード エディタの OnLoadOnSwitchViewOnContextChangeOnSign のいずれかに対するイベント ハンドラのスタブにフォーカスが切り替わります。

フォームの OnSubmitRequest イベントに対するイベント ハンドラを追加する

  1. [ツール] メニューの [送信オプション] をクリックします。

  2. [ユーザーによるこのフォームの送信を許可する] チェック ボックスをオンにして、[コードを使用してユーザー設定操作を実行する] をクリックします。

  3. [コードの編集] をクリックし、[OK] をクリックします。

    コード エディタの OnSubmitRequest イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

フォームの OnSaveRequest イベントに対するイベント ハンドラを追加する

  1. [ツール] メニューの [フォームのオプション] をクリックします。

  2. [開く/保存] カテゴリで、[ユーザー設定コードを使って保存] をクリックして [編集] をクリックします。

    コード エディタの OnSaveRequest イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

フォームの OnVersionUpgrade イベントに対するイベント ハンドラを追加する

  1. [ツール] メニューの [フォームのオプション] をクリックします。

  2. [プログラミング] カテゴリで、[バージョンのアップグレード] ボックスの一覧の [ユーザー設定イベントの使用] をクリックし、[編集] をクリックします。

    コード エディタの OnVersionUpgrade イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

フォームの OnMergeRequest イベントに対するイベント ハンドラを追加する

  1. [ツール] メニューの [フォームのオプション] をクリックします。

  2. [詳細設定] カテゴリで、[フォームの結合を有効にする] チェック ボックスと [ユーザー設定コードを使って結合する] チェック ボックスをオンにして、[編集] をクリックします。

    コード エディタの OnMergeRequest イベントに対するイベント ハンドラのスタブにフォーカスが切り替わります。

OnAfterImport イベントに対するイベント ハンドラを追加する

OnAfterImport イベントのイベント ハンドラを追加するには、マネージ コードのフォーム テンプレートのフォーム コードを開き、イベント ハンドラ関数を手動で追加する必要があります。このイベントのイベント ハンドラを作成する方法については、OnAfterImport イベントのリンクをクリックしてください。

セカンダリ データ ソースに対するイベント ハンドラを追加する

次の例では、セカンダリ データ ソースにイベント ハンドラを追加する方法を示します。この例では、次のスキーマを持つ books.xml というリソース ファイルからのセカンダリ データ ソースを想定しています。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="catalog">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="book" minOccurs="0" maxOccurs="unbounded"></xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="genre" type="xsd:string"></xsd:element>
    <xsd:element name="author" type="xsd:string"></xsd:element>
    <xsd:element name="book">
        <xsd:complexType>
            <xsd:all>
                <xsd:element ref="author" minOccurs="0" maxOccurs="1"></xsd:element>
                <xsd:element ref="title" minOccurs="0" maxOccurs="1"></xsd:element>
                <xsd:element ref="genre" minOccurs="0" maxOccurs="1"></xsd:element>
                <xsd:element ref="price" minOccurs="0" maxOccurs="1"></xsd:element>
                <xsd:element ref="publish_date" minOccurs="0" maxOccurs="1"></xsd:element>
                <xsd:element ref="description" minOccurs="0" maxOccurs="1"></xsd:element>
            </xsd:all>
            <xsd:attribute ref="id"></xsd:attribute>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="price" type="xsd:string"></xsd:element>
    <xsd:element name="title" type="xsd:string"></xsd:element>
    <xsd:element name="publish_date" type="xsd:string"></xsd:element>
    <xsd:element name="description" type="xsd:string"></xsd:element>
    <xsd:attribute name="id" type="xsd:string"></xsd:attribute>
</xsd:schema>

このデータ ソースからフォームのビューが作成されます。フォーム コードは著者と著者が書いた本の数に基づいてハッシュ テーブルを作成します。ビューに表示されるテーブルから項目を更新すると、OnAfterChange イベント ハンドラがハッシュ テーブルを更新します。InfoPathEventHandler 属性 (InfoPathEventHandlerAttribute クラスによって実装される) の DataObject プロパティを使用してセカンダリ データ ソースが参照される点に注意してください。

namespace AuxDom
{
    // InfoPathNamespace attribute goes here.
    public class AuxDom
    {
        private XDocument thisXDocument;
        private Application thisApplication;
        private Hashtable authors;

        public void _Startup(Application app, XDocument doc)
        {
            thisXDocument = doc;
            thisApplication = app;

            authors = new Hashtable();
        }

        public void _Shutdown()
        {
            authors.Clear();
        }

        // The following function handler is created by Microsoft
        // Office InfoPath. Do not modify the type or number of
        // arguments. 
        [InfoPathEventHandler(EventType=InfoPathEventType.OnLoad)]
        public void OnLoad(DocReturnEvent e)
        {
            IXMLDOMDocument books = thisXDocument.GetDOM("books");
            DOMNodeList externalAuthors = books.selectNodes("/catalog/book/author");
            foreach (IXMLDOMNode authorNode in externalAuthors)
            {
                AddBookFromAuthor(authorNode.text);
            }
        }

        // The following function handler is created by Microsoft
        // Office InfoPath. Do not modify the type or number of
        // arguments. 
        [InfoPathEventHandler(MatchPath="/catalog/book/author", EventType=InfoPathEventType.OnAfterChange, DataObject="books")]
        public void books__author_OnAfterChange(DataDOMEvent e)
        {
            if (e.IsUndoRedo)
            {
                // An undo or redo operation has occurred and the DOM 
                // is read-only.
                return;
            }
            
            if (e.Source.text != e.NewValue.ToString())
            {
                RemoveBookFromAuthor(e.OldValue.ToString());
                AddBookFromAuthor(e.NewValue.ToString());
            }
        }

        private void AddBookFromAuthor(string authorName)
        {
            if (authors.Contains(authorName))
            {
                authors[authorName] = (int)authors[authorName] + 1;
            }
            else
            {
                authors.Add(authorName, 1);
            }
        }

        private void RemoveBookFromAuthor(string authorName)
        {
            if (authors.Contains(authorName))
            {
                authors[authorName] = (int)authors[authorName] - 1;
            }
            if ((int)authors[authorName] == 0)
            {
                authors.Remove(authorName);
            }
        }

        // The following function handler is created by Microsoft
        // Office InfoPath. Do not modify the type or number of
        // arguments. 
        [InfoPathEventHandler(MatchPath="ShowAuthors", EventType=InfoPathEventType.OnClick)]
        public void ShowAuthors_OnClick(DocActionEvent e)
        {
            // Write your code here.
            StringBuilder report = new StringBuilder();

            foreach (string authorName in authors.Keys)
            {
                report.Append(authorName + ",\t\t\t");
                report.Append(authors[authorName] + "\n");
            }

            thisXDocument.UI.Alert(report.ToString());
        }
    }
}

イベント ハンドラを含むクラスの識別方法

InfoPath 2003 のマネージ コード オブジェクト モデルと互換性のある新しい InfoPath フォーム テンプレート プロジェクトを作成すると、フォーム コード モジュール先頭のクラスにアセンブリ レベルの System.ComponentModel.Description 属性が適用され、これによってフォーム テンプレートのすべてのイベント ハンドラを含むクラスが識別されます。

メモ重要 :

このクラスの System.ComponentModel.Description 属性は変更しないでください。変更すると、イベント ハンドラがどこにあるかをフォーム テンプレートを特定できず、イベント ハンドラが実行されません。

using System;
using Microsoft.Office.Interop.InfoPath.SemiTrust;

// Office integration attribute. Identifies the startup class for the // form. Do not modify.
[assembly: System.ComponentModel.DescriptionAttribute(    "InfoPathStartupClass, Version=1.0, Class=Template1.FormCode")]

Imports System
Imports Microsoft.Office.Interop.InfoPath.SemiTrust

' Office integration attribute. Identifies the startup class for the form. Do not modify.
<Assembly: System.ComponentModel.DescriptionAttribute( _    "InfoPathStartupClass, Version=1.0, Class=Template1.FormCode")>

イベント ハンドラの識別方法

InfoPath のデザイン モード ユーザー インターフェイスのメニュー コマンドまたはボタンを使用して新しいイベント ハンドラを追加すると、イベント ハンドラ関数のスタブがフォームに書き込まれます。次の例では、total というフィールドの OnValidate を追加したときに作成されるスタブ イベント ハンドラを示します。

[C#]

[InfoPathEventHandler(MatchPath="/invoice/total", EventType=InfoPathEventType.OnValidate)]
public void total_OnValidate(DataDOMEvent e)
{
    // Write your code here.
}

[Visual Basic]

<InfoPathEventHandler(MatchPath:="/invoice/total",EventType:= OnValidate)> Public Sub total_OnValidate(ByVal e As EventArgs)
    ' Write your code here.

End Sub

用意されたスタブに、thisXDocument 変数または thisApplication 変数のキャッシュされるプライベート メンバを使用したり、イベント ハンドラが受け取る e EventArgs オブジェクトからアクセスするメンバを使用したりして、InfoPath オブジェクト モデルのメンバを起動するコードを追加できます。

[C#]

thisXDocument.UI.Alert.(e.Site.text);

[Visual Basic]

thisXDocument.UI.Alert.(e.Site.text)

InfoPathEventHandler 属性 (InfoPathEventHandlerAttribute クラスで定義される) は、イベント ハンドラとして使用する関数のカスタム属性です。

イベントに必要な場合、MatchPath パラメータ (InfoPathEventHandlerAttribute クラスの MatchPath プロパティで定義される) はイベント ソースを識別する XPath 式を示しています。EventType パラメータ (InfoPathEventHandlerAttribute クラスの EventType プロパティで定義される) はイベントの種類を示しています。これらのパラメータの値は変更しないでください。これらのパラメータの値を変更すると、イベント ハンドラが正しくコンパイルされないことや、イベント通知が予定どおりに発生しないことがあります。

イベント ハンドラのコードを隠ぺいする

マネージ コードのフォーム テンプレートをコンパイルしたときに生成されるアセンブリ (projectname.dll) に隠ぺいユーティリティを実行すると、ユーザーがフォームを開いたときに InfoPath がアセンブリを読み込めません。イベント ハンドラやその他のコードを隠ぺいする必要がある場合は、隠ぺいするコードを別のアセンブリに置き、プロジェクトでそのアセンブリを参照し、参照先アセンブリのメンバを FormCode.cs または FormCode.vb から呼び出してください。隠ぺいユーティリティは参照するアセンブリだけに実行することが重要です。

関連項目

概念

[方法] InfoPath 2003 オブジェクト モデルを使用してフォーム イベントに応答する方法