プログラムを使用してプロバイダー ホスト型アドインにカスタム ボタンを展開する
これは、プロバイダー ホスト型の SharePoint アドインの開発の基本に関する記事のシリーズの 9 番目です。SharePoint アドイン とこのシリーズの前の記事 (プロバイダー ホスト型の SharePoint アドインの作成を始めるにある記事) をよく理解しておいてください。
注:
プロバイダー ホスト型アドインに関するこのシリーズに沿って作業してきた場合は、このトピックでも引き続き使用できる Visual Studio ソリューションを既に所有しています。 また、「SharePoint_Provider-hosted_Add-Ins_Tutorials」でリポジトリをダウンロードして BeforeProgrammaticButton.sln ファイルを開くこともできます。
この記事では、ボタンを取得するリボンのリスト自体が全く同じアドインでプログラムで展開されている場合に、SharePoint アドインにカスタム リボン ボタンを含める方法について説明します。
プロジェクトにカスタム ボタンを再度追加する
注:
Visual Studio のスタートアップ プロジェクトの設定は、ソリューションが開かれるたびに、既定値に戻される傾向があります。 このシリーズ記事のサンプル ソリューションを再開した直後は、次の手順を必ず実行してください。
- ソリューション エクスプローラーの上部にあるソリューション ノードを右クリックして、[スタートアップ プロジェクトの設定] を選択します。
- 3 つすべてのプロジェクトが [アクション] 列で [開始] に設定されていることを確認します。
前の記事では、カスタム AddEmployeeToCorpDB リボン ボタンをプロジェクトから削除しました。 以下の手順を使用して再度追加します。
ソリューション エクスプローラーの上部にあるツール バーで、[すべてのファイルを表示] ボタンを選択します。
図 1. ソリューション エクスプローラー ツール バー
ChainStore プロジェクトで、AddEmployeeToCorpDB を右クリックして、[プロジェクトに含める] を選択します。
もう一度、[すべてのファイルを表示] ボタンを選択します。
ChainStore プロジェクトで AddEmployeeToCorpDB を展開し、elements.xml ファイルを開きます。
ジレンマとその解決方法について理解する
elements.xml ファイルで、 CustomAction 要素の RegistrationId 属性は、リボンにボタンが追加されたリスト を識別します ( {$ListId:Lists/Local Employees;}
)。 リストは既にホスト Web に手動で追加されていた場合は正しく動作しました。 しかし今回は初回実行時のロジックでプログラムによりリストを展開するので、SharePoint がアドインをインストールしボタンを展開しようとしてもリストがまだ存在していません。 それで、アドインのインストール時に例外がスローされ失敗します。
初回実行時のロジックではなく、イベント ハンドラーのインストールでリストを展開しても、ジレンマは解決されません。これは、SharePoint が、カスタム ハンドラーを実行する前に、記述的に定義されたカスタム コンポーネント (カスタム ボタン (および [注文] アドイン パート) など) を展開するためです。このため、SharePoint がボタンの展開を試みてもリストは存在しないことになります。
カスタム ボタンをプログラムで完全に作成することは、ここでは高度すぎるため実際的ではありません。 また、特に必要もありません。 プログラムを一部にのみ使用してカスタム ボタンを作成し、それをカスタム リストに割り当てる方が比較的簡単です。
基本的な手順は次のとおりです。
記述的に定義されたボタンをプロジェクトに保存します。ただし、同じアドインを使用してプログラムで展開されるリストではなく、SharePoint サイトに常に存在する何らかのリボンに割り当てます。
初回実行時のロジックで、リストをプログラムで作成した後、未定義のボタンをリストのリボンにプログラムで追加します。
元のボタンの値を使用して、新しいボタンのプロパティを初期化します。 この時点で 2 つの同じボタンがあります。 2 つ目のボタンは [ローカル従業員] リストのリボンに割り当てられます。
プログラムで元のボタンを削除します。
プログラムでカスタム ボタンを登録する
次の手順は、この戦略を実装する方法を示しています。
ChainStore プロジェクトで AddEmployeeToCorpDB を展開し、elements.xml ファイルを開いて CustomAction 要素の RegistrationId 属性の値を "100" に変更します。 これは、リストの種類の ID です。 Web サイトにこの種類のリストのインスタンスがない場合でも、このリストの種類はすべての SharePoint Web サイトにあります。 属性は次のようになります。
RegistrationId="100"
ファイル SharePointComponentDeployer.cs で、以下の行を DeployChainStoreComponentsToHostWeb メソッドの、
CreateLocalEmployeesList
を呼び出す行のすぐ下に追加します (次の手順でこのメソッドを作成します)。ChangeCustomActionRegistration();
SharePointComponentDeployer
クラスに、次のメソッドを追加します。private static void ChangeCustomActionRegistration() { using (var clientContext = sPContext.CreateUserClientContextForSPHost()) { var query = from action in clientContext.Web.UserCustomActions where action.Name == "{button_GUID} .AddEmployeeToCorpDB" select action; IEnumerable<UserCustomAction> matchingActions = clientContext.LoadQuery(query); clientContext.ExecuteQuery(); UserCustomAction webScopedEmployeeAction = matchingActions.Single(); // TODO8: Get a reference to the (empty) collection of custom actions // that are registered with the custom list. // TODO9: Add a blank custom action to the list's collection. // TODO10: Copy property values from the descriptively deployed // custom action to the new custom action // TODO11: Delete the original custom action. clientContext.ExecuteQuery(); } }
このコードについては、次の点に注意してください。
カスタム アクション (つまり、カスタム ボタン) はリストの種類のリボンに登録されているため、スコープは Web サイト全体であり、カスタム アクションの Web サイトのコレクション内に存在します。 このため、コードを実行すると、カスタム アクションはそのコレクションから取得されます。
の
action.Name
値は、AddEmployeeToCorpDB のelements.xml ファイル内の CustomAction 要素の ID 属性から取得されます。
重要
コード内の
action.Name
値は、elements.xml ファイルの値と一致するように変更する必要があります。 名前の GUID 部分は異なります。 GUID と名前の他の部分の間には、"."
文字が付加されています。 行の例を次に示します。where action.Name == "4a926a42-3577-4e02-9d06-fef78586b1bc.AddEmployeeToCorpDB"
TODO8
を次のコードに置き換えます。 アドインを取り消すとき、アドインで作成されたコンポーネントは削除されないことに注意してください。 最初にロジックを実行すると、リストの UserCustomActions コレクションでカスタム アクションが生じ、次に F5 を選択したときも取り消されません。 混乱を避けるため、このコードlistActions.Clear();
の最後の行によってコレクションが空になります。var queryForList = from list in clientContext.Web.Lists where list.Title == "Local Employees" select list; IEnumerable<List> matchingLists = clientContext.LoadQuery(queryForList); clientContext.ExecuteQuery(); List employeeList = matchingLists.First(); var listActions = employeeList.UserCustomActions; clientContext.Load(listActions); listActions.Clear();
TODO9
を次の行に置き換えます。これにより、未定義のカスタム アクションが [ローカル従業員] のリストに追加されます。var listScopedEmployeeAction = listActions.Add();
TODO10
を次のコードに置き換えます。listScopedEmployeeAction.Title = webScopedEmployeeAction.Title; listScopedEmployeeAction.Location = webScopedEmployeeAction.Location; listScopedEmployeeAction.Sequence = webScopedEmployeeAction.Sequence; listScopedEmployeeAction.CommandUIExtension = webScopedEmployeeAction.CommandUIExtension; listScopedEmployeeAction.Update();
このコードについては、次の点に注意してください。
このコードは、Web スコープ ボタン (記述されているマークアップで展開されている) のプロパティ値を、リスト スコープのボタンの対応するプロパティに割り当てます。このため、2 つのボタンは、スコープ以外は同じものです。
Sequence プロパティは、リボンのこのエリアに表示されるボタンの相対的な順序を指定します。 この場合、ボタンはリボンの [項目] タブの [アクション] セクションに表示されます。 説明的なマークアップにより、この値は 10001 に設定されています。この値は、SharePoint によってリボンの [アクション] セクションに配置されるどの組み込みボタンよりも後、つまり右側に表示されるようにするために十分な大きさです。
TODO11
を次の行と置き換えると、説明的に定義された元のボタンが削除されます。 この行がない場合、リスト テンプレート "100" を使用する Web サイトのすべてのリストにカスタム ボタンが追加されます。 ボタンの機能は [ローカル従業員] リストと密接に関係しているため、その他のリストにボタンを追加しても意味はありません。 また、この行がないと、[ローカル従業員] リストにボタンが 2 回表示されます。このリストではテンプレート "100" が使用されるためです。webScopedEmployeeAction.DeleteObject();
これで、メソッド全体は次のようになります (ただし、プレースホルダーの代わりに GUID が使用されるはずです)。
private static void ChangeCustomActionRegistration() { using (var clientContext = SPContext.CreateUserClientContextForSPHost()) { var query = from action in clientContext.Web.UserCustomActions where action.Name == "{button_GUID} .AddEmployeeToCorpDB" select action; IEnumerable<UserCustomAction> matchingActions = clientContext.LoadQuery(query); clientContext.ExecuteQuery(); UserCustomAction webScopedEmployeeAction = matchingActions.Single(); var queryForList = from list in clientContext.Web.Lists where list.Title == "Local Employees" select list; IEnumerable<List> matchingLists = clientContext.LoadQuery(queryForList); clientContext.ExecuteQuery(); List employeeList = matchingLists.First(); var listActions = employeeList.UserCustomActions; clientContext.Load(listActions); listActions.Clear(); var listScopedEmployeeAction = listActions.Add(); listScopedEmployeeAction.Title = webScopedEmployeeAction.Title; listScopedEmployeeAction.Location = webScopedEmployeeAction.Location; listScopedEmployeeAction.Sequence = webScopedEmployeeAction.Sequence; listScopedEmployeeAction.CommandUIExtension = webScopedEmployeeAction.CommandUIExtension; listScopedEmployeeAction.Update(); webScopedEmployeeAction.DeleteObject(); clientContext.ExecuteQuery(); } }
ホスト Web のフル コントロールを要求する
アドインは Web スコープのカスタム アクションを追加および削除するので、アドインが要求するアクセス許可を [管理] から [フル コントロール] に昇格させる必要があります。
ソリューション エクスプローラーで、ChainStore プロジェクトの AppManifest.xml ファイルを開きます。
[アクセス許可] タブを開きます。[スコープ] 値は [Web] のままにしますが、[アクセス許可] フィールドで、ドロップダウンから [フル コントロール] を選択します。
ファイルを保存します。
アドインを実行してボタンの展開をテストする
香港ストアの Web サイトの [サイト コンテンツ] ページを開き、[ローカル従業員] リストを削除します。
注:
Visual Studio でアドインを取り消しても、アドインで作成されたリストは削除されないため、リストを作成するコードをテストする場合は手動でリストを削除する必要があります。
F5 キーを使用して、アドインを展開して実行します。 Visual Studio は、IIS Express でリモート Web アプリケーションをホストして、SQL Express で SQL データベースをホストします。 また、テスト用 SharePoint サイトにアドインを一時的にインストールして、すぐにアドインを実行します。 開始ページが表示される前に、アドインへのアクセス許可を付与するように求めるダイアログが表示されます。
アドインの開始ページが開いたら、上部のクロム コントロールにある [サイトに戻る] リンクを選択します。
[サイト コンテンツ] ページに移動します。 [ローカル従業員] リストは、初回実行時のロジックで追加されるため、既に存在します。
注:
リストがない、または最初に実行すべきコードが実行されていないことを示す他の症状がある場合、F5 を選択したときに [テナント] テーブルが空の状態に戻されていない可能性があります。 最も一般的な原因として、ChainCorporateDB プロジェクトが Visual Studio でスタートアップ プロジェクトとしてもはや設定されていないことが考えられます。 この修正方法については、この記事の上部にある注記を参照してください。 また、「各デバッグ セッションで企業のデータベースを再構築するため、Visual Studio を構成する」で説明されているとおり、再構築するためのデータベースが構成してあることを確認してください。
リストを開き、アイテムを追加します。
リスト ビューで項目を選択し、リボン上の [項目] タブを開きます。
[項目] タブで [企業 DB への追加] ボタンを選択します。 従業員が企業のデータベースに追加され、[企業 DB に追加] フィールドが [はい] に変更されます。
[サイト コンテンツ] ページに戻り、[アドインの追加] を選択します。
新しい [カスタム リスト] を追加します。 既定では、この種類は "一般" です (一般はリスト種類 100) です。 リストが作成されたら、リボン上の [項目] タブを開きます。 [企業 DB に追加] ボタンはリボン上にはないことに注意してください。 これは、コードによって Web スコープ ボタンが削除されたためです。
デバッグ セッションを終了するには、ブラウザー ウィンドウを閉じるか、Visual Studio でデバッグを停止します。 F5 キーを選択するたびに、Visual Studio は以前のバージョンのアドインを取り消し、最新のバージョンをインストールします。
このアドインおよび他の記事の Visual Studio ソリューションを操作し、それが終了したら前回のアドインを取り消すとよいでしょう。 ソリューション エクスプローラーでプロジェクトを右クリックして、[取り消し] を選択します。
次の手順
SharePoint では、リスト上のイベントおよびリスト アイテムにも、カスタム ハンドラーがあります。 「プロバイダー向けのホスト型アドインでリスト アイテム イベントを処理する」では、これを作成し、最初に実行するロジックにこれを適用する方法について説明します。