Office365でSilverlightを動かしてみる #実装編

「Office365でSilverlightを動かしてみる #コーディング編」で、サンドボックス ソリューションとしての
Silverlight Webパーツのコーディングも終わりましたので、実際にOffice365へ実装してみたいと思います。

実装する前にひとつ注意点を挙げます。
Office365にアップする際のパーツの名前です。

上記では「SilverlightWebPart1」として追加されます。
よって、ここの名前を分かり易い名前にしておくのが良いでしょう。

Ⅰ.ローカルでの動作検証

1. まずはローカル環境で動作するか試してみましょう。
  ただローカルはSharePoint環境であって、Office365(SharePoint Online)環境ではないのでローカルで
  動作してもOffice365では動作しない可能性もあるので注意が必要です。
  F5を押します。
  SharePointのログイン画面が表示されるので、ログインしましょう。
  

2. ログインすると、SharePointのTOP画面が表示されます。
  「編集」マークのようなタブを選択します。
  

3. 「編集ツール」メニューが表示されます。
  「挿入」を選択すると「Webパーツ」というメニューが表示されるので選択します。
  

4. 「Webパーツ」を選択するとカテゴリが表示されます。
  カスタムパーツは「Custom」カテゴリとして表示されます。
  

  今回作成したのは、「SilverlightWebPart1」なので選択して「追加」ボタンを押します。

5. 「SilverlightWebPart1」が追加できました。
  必ず「保存して閉じる」を押しましょう。でないと、画面に追加したパーツが保存されません。
  

6. それでは追加したパーツが正しく動作するか試してみましょう。
  適当な動画ファイルをSharePoint上に配置しておきます。
  「サイトの操作」→「SharePoint Designerで編集」を選択します。
  

7. 「SharePoint Designer」のログイン画面が表示されるので、SharePoint同様にログインしましょう。
  ログインしたら「SharePoint Designer」のトップ画面が表示されます。
  

  なんか見たかんじエクスプローラっぽい表示ですね。
  サイトもフォルダになっているので、ドラッグアンドドロップでファイルをアップロードできます。
  「11」サイトを作ってテストしているので、とりあえず、「11」→「images」に動画ファイルを置きます。
  

8. Silverlight WebパーツのURL欄にさきほどアップした動画のURLを入力します。
  URLを入力したら「Play」ボタンを押します。(URLをコピーして貼り付けた方が早いです)
  動画が表示されれば、OKです。
  

  「Pause」、「Stop」ボタンも動作するか試しましょう。
  問題無ければローカル検証は終了です。

Ⅱ.パッケージ

ここまでは、ローカル(SharePoint)環境での動作検証でした。
では、実際にOffice365(SharePoint Online)上でも動作するか試してみましょう。
でもOffice365に何をアップロードすればいいのでしょう?

アップロードするのは、”パッケージ(.wsp)”です。

それでは、パッケージを作成してみましょう。
Visual Studio 2012のメインメニューから「ビルド(B)」→「ソリューションの配置(D)」を選択します。
コレだけですw
ガガガーと色んなファイルが生成されていますが、最終的にはパッケージファイル(.wsp)に纏まります。
端的に言えば、zipファイルのようなものでしょうか。

今回のソリューションの配置で、「EAP_Office365_Parts.wsp」がパッケージとして作成されました。

Ⅲ.Office365での動作検証

さて、ローカルでの動作検証も終え、パッケージも作成したので、Office365へパッケージをアップしてみましょう。

1. Office365(SharePoint Online)の「サイトの操作」→「サイトの設定」を選択します。
  

2. サイト設定の項目がいっぱいあるのですが、その中から「ギャラリー」→「ソリューション」を選択します。
  

3. ソリューション画面が表示されたら、「ソリューションのアップロード」を選択します。
  

4. パッケージファイル(EAP_Office365_Parts.wsp)を選択します。
  選択が終わったら「OK」ボタンを押します。
  これでソリューションを追加します。
  

5. ソリューションが追加されたら、アクティブ化の画面が表示されます。
  追加された状態は「非アクティブ」とされているため、”アクティブ化”が必要です。
  「アクティブ化」を選択してアクティブにしましょう。
  

6. ソリューション一覧が表示されますが、「EAP_Office365_Parts」が新しく追加されています。
  

7. あとは、「ローカルでの動作検証」の3番から同じ手順でWebパーツを追加して動作検証を行います。
  「ueno_test」というサブサイトを作成しているので、ココにSilverlight Webパーツを追加してみます。
  

8. 動画ファイルもOffice365にアップしておきましょう。
  それでは、動かしてみます。
  

  動きました!
  単純な機能だから問題ないだろうとは思っていましたが、実際に動いてくれるとうれしいですね。

これでOffice365(SharePoint Online)上での動作検証が完了しました。

コーディングからローカル検証~Office365検証まで簡単ではありますが、書かせていただきました。
少しでも参考にしていただければ幸いです。

SharePointでリスト(List)の疑似的ロック機構(Lock)を作成し連番生成(sequential number auto generator)する。(Silverlight, C#, List)

SharePointでは ユーザからList(リスト)のロック機構がありません。

(SQLでいうとテーブルロック、行ロック等のSQLで重要な機能が使えません)

Document Library(ドキュメントライブラリ) のChekOut/CheckIn(チェックアウト/チェックイン)はありますが、やりたいことは違います。

ここで困るのは、どうやって複数ユーザからくる連番を生成を矛盾なく生成(sequential number generator)するか問題になります。

世界中のサイト(MSや個人サイト)を検索しましたが、みんな困っているし、だれも解決していないのですが、原始的な方法がありますので。

その方法を説明します。

方法1:Webサービスで外部でロックできるDatabase Engineで生成する。(これは誰でもできそうなので省略します。)

方法2:SharePointに疑似的リストロック機構を作る。

まず以下で説明した。見積ヘッダー、見積明細でサンプルを説明します。

SharePointで伝票形式(ヘッダー、行)を複数(Multiple)のListで作るときの最適なキー(sequential number auto generator)の持ち方。(Silverlight, C#, List)

以下のような感じでロックリスト・連番リストを作成します。
見積ロックリスト

ID SEQNo
1 10001
2 10002

連番リスト

ID SEQNo SEQNoMain
1 1001 1

List_Quotation_Lock- Shmea.xml (見積ロックリスト)
18行目のように検索するときに重要な項目は以下のように設定してください。

  1. 必須:Required=”TRUE”
  2. ユニーク:EnforceUniqueValues=”TRUE”
  3. インデックス:Indexed=”TRUE”
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="List_Quotation_Lock" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/List_Quotation_Lock" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100139d7d207b6f48fc889c801512ddd21f" Name="ListFieldsContentType">
        <FieldRefs>
          <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" />
          <FieldRef ID="{9da4e1bd-46a7-4756-8607-39dd18df2359}" Name="SEQNo" />
        </FieldRefs>
      </ContentType>
      <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
    </ContentTypes>
    <Fields>
      <Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Type="Text" Name="Title" DisplayName="$Resources:core,Title;" Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title" MaxLength="255" />
      <Field Name="SEQNo" ID="{9da4e1bd-46a7-4756-8607-39dd18df2359}" DisplayName="SEQNo" Type="Number" Required="TRUE" EnforceUniqueValues="TRUE" Indexed="TRUE"/>
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="ID" />
          <FieldRef Name="SEQNo" />
          <FieldRef Name="Attachments"></FieldRef>
          <FieldRef Name="LinkTitle"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

List_SEQNo- Shmea.xml (連番リスト)
19,20行目のように検索するときに重要な項目は以下のように設定してください。

  1. 必須:Required=”TRUE”
  2. ユニーク:EnforceUniqueValues=”TRUE”
  3. インデックス:Indexed=”TRUE”
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="List_SEQNo" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/List_SEQNo" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100b3669d5da61a455da30196fbe3b98886" Name="ListFieldsContentType">
        <FieldRefs>
          <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" />
          <FieldRef ID="{3e4dcade-a0d7-48b3-b0cb-5a5cd8e49cf9}" Name="SEQNo" />
          <FieldRef ID="{40cb335d-fcab-49eb-90d3-039c30f97649}" Name="SEQNoMain" />
        </FieldRefs>
      </ContentType>
      <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
    </ContentTypes>
    <Fields>
      <Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Type="Text" Name="Title" DisplayName="$Resources:core,Title;" Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title" MaxLength="255" />
      <Field Name="SEQNo" ID="{3e4dcade-a0d7-48b3-b0cb-5a5cd8e49cf9}" DisplayName="SEQNo" Type="Number" Required="TRUE" EnforceUniqueValues="TRUE" Indexed="TRUE" />
      <Field Name="SEQNoMain" ID="{40cb335d-fcab-49eb-90d3-039c30f97649}" DisplayName="SEQNoMain" Type="Number" Required="TRUE"/>
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="ID" />
          <FieldRef Name="SEQNo" />
          <FieldRef Name="SEQNoMain" />
          <FieldRef Name="LinkTitle" />
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

プログラムにて連番をとります。

仕組み:

  1. 連番を取得するときに、1度[List_Quotation_Lock]にレコードを追加しておきます。そのときに追加するレコードはユニークが設定されているSEQNoには必ず同一キーを設定(今回は”0″)することにより、疑似的排他ロックをします。
  2. この時点でほかのユーザが連番を取得しようと、[List_Quotation_Lock]にレコードを追加しても、ユニークキーエラーになります。エラー時にはユーザに「しばらくまってから実行してください」と表示します。(プログラムで数回リトライするか、キュー等を使って処理すればもっといいかも。)
  3. 疑似的ロックができたので、[List_SEQNo]から連番を取得して、連番に[+1]して更新します。
  4. 連番を取り終わったら、[List_Quotation_Lock]からロックレコードを削除しておきます。

サンプルプログラム:
267~346が連番をとるプログラムです。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using SP = Microsoft.SharePoint.Client;
//using System.Collections.ObjectModel;
using System.Collections.ObjectModel;

using System.ComponentModel;

namespace SilverlightProjectMain.Models.SharepointClient.Base
{
    //デリゲート
    public delegate void Adapter_EventHandler(bool IsSuccess, Exception e);
    public delegate void Adapter_EventHandler<Type>(bool IsSuccess, Exception e, Type typeData);
    public delegate void Adapter_EventHandlerListItemCollection(bool IsSuccess, Exception e, SearchType searchType, SP.ListItemCollection listItemsMain, SP.ListItemCollection listItemsSub);
    public delegate void Adapter_EventHandlerCollection<Type>(bool IsSuccess, Exception e, System.Collections.ObjectModel.ObservableCollection<Type> observableCollection);
    public delegate void Adapter_EventHandlerCollection<Type1, Type2>(bool IsSuccess, Exception e, System.Collections.ObjectModel.ObservableCollection<Type1> observableCollection1, System.Collections.ObjectModel.ObservableCollection<Type2> observableCollection2);

    public class CData : INotifyPropertyChanged

    {
        public int ID { get; set; }
        public int SEQNo { get; set; }

        #region INotifyPropertyChanged メンバ
        /// <summary>
        /// プロパティ変更時のイベント
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }

        protected virtual void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
        #endregion

    }

    public enum SearchType
    {
        SEQNo,
        All,
        Type001,
        Type002,
        Type003,
        Type004,
        Type005
    }

    public class Adapter_Base_List
    {
        private const int DEFAULT_ROWLIMIT = 30;

        protected string _strListMain = string.Empty;
        protected string _strListSub = string.Empty;
        protected string _strListDoc = string.Empty;
        protected int _nListSEQNo_SEQNo = int.MinValue;
        protected string _strListLock = string.Empty;

        //Sample 動作OKのCAML
        //var camlQuery = new SP.CamlQuery();
        //camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='ID' /><Value Type='Integer'>1</Value></Eq></Where></Query></View>";
        //camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='CustomerName' /><Value Type='Text'>111</Value></Eq></Where></Query></View>";
        //camlQuery.ViewXml = "<View><Query><Where><Contains><FieldRef Name='CustomerName' /><Value Type='Text'>111</Value></Contains></Where></Query></View>";

        //その他キーワード(StartWith, In)

        //listItems = list.GetItems(camlQuery);
        //clientContext.Load(listItems);

        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list)
        {
            return GetItemsFromCAMLQuery(list, "", "", DEFAULT_ROWLIMIT);
        }
        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list, string strWhere)
        {
            return GetItemsFromCAMLQuery(list, strWhere, "", DEFAULT_ROWLIMIT);
        }

        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list, string strWhere, string strOrderBy)
        {
            return GetItemsFromCAMLQuery(list, strWhere, strOrderBy, DEFAULT_ROWLIMIT);
        }

        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list, string strWhere, string strOrderBy, int nRowLimit)
        {
            var camlQuery = new SP.CamlQuery();

            string strTemp = "<View>";
            strTemp += "<Query>" + strWhere + "</Query> ";
            strTemp += "<RowLimit>" + nRowLimit.ToString() + "</RowLimit>";
            strTemp += strOrderBy;
            strTemp += "</View>";

            camlQuery.ViewXml  = strTemp;
            return list.GetItems(camlQuery);
        }

        static protected string GetWhere_SEQNo(int nSEQNo)
        {
            return "<Where><Eq><FieldRef Name='SEQNo' /><Value Type='Integer'>" + nSEQNo.ToString() + "</Value></Eq></Where>";
        }

        static protected string GetWhere_PersonSEQNo(int nSEQNo)
        {
            return "<Where><Eq><FieldRef Name='PersonSEQNo' /><Value Type='Integer'>" + nSEQNo.ToString() + "</Value></Eq></Where>";
        }

        static protected string GetOrderby_ID()
        {
            return "<OrderBy><FieldRef Name='ID'></FieldRef></OrderBy>";
        }

        static protected string GetWhere_FileLeafRef(string strDocumentName)
        {
            return "<Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>" + strDocumentName + "</Value></Eq></Where>";
        }

        static protected void DeleteAllItems(SP.List list, SP.ListItemCollection  listItems)
        {
            foreach (var li in listItems)
            {
                SP.ListItem item = list.GetItemById(li.Id);
                item.DeleteObject();
            }
        }

        ////////////////////////////////////////////////////////////////////////////
        ///  検索処理
        ////////////////////////////////////////////////////////////////////////////
        protected void AsyncDownload_Sub(Adapter_EventHandlerListItemCollection adapter_EventHandler, SearchType searchType, int nSEQNo, string strCustomerName)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.List listMain = null;
                SP.List listSub = null;

                SP.ListItemCollection listItemsMain = null;
                SP.ListItemCollection listItemsSub = null;

                string strWhere = string.Empty;
                string strOrderBy = string.Empty;

                listMain = clientContext.Web.Lists.GetByTitle(_strListMain);

                if (!string.IsNullOrEmpty(_strListSub))
                {
                    listSub = clientContext.Web.Lists.GetByTitle(_strListSub);
                }

                switch (searchType)
                {
                    //nSEQNoで検索(SPList.GetItemById)
                    case SearchType.SEQNo:
                        strWhere = GetWhere_SEQNo(nSEQNo);
                        listItemsMain = GetItemsFromCAMLQuery(listMain, strWhere);

                         //明細行取得
                        if (!string.IsNullOrEmpty(_strListSub))
                        {
                            strWhere = GetWhere_PersonSEQNo(nSEQNo);
                            strOrderBy = "<OrderBy><FieldRef Name=\"No\"></FieldRef></OrderBy>";
                            listItemsSub = GetItemsFromCAMLQuery(listSub, strWhere, strOrderBy);
                            clientContext.Load(listItemsSub);
                        }
                        break;

                    //全件検索(SP.CamlQuery)
                    case SearchType.All:
                        listItemsMain = GetItemsFromCAMLQuery(listMain);
                        break;

                    //検索キーワードを含む(SP.CamlQuery)
                    case SearchType.Type001:
                        //完全一致;    column =‘SearchWord’
                        //listItems = GetItemsFromCAMLQuery(list, "<Where><Eq><FieldRef Name='CustomerName' /><Value Type='Text'>" + strCustomerName + "</Value></Eq></Where>");

                        //検索キーワードを含む: column like ‘%SearchWord%’
                        strWhere = "<Where><Contains><FieldRef Name='CustomerName' /><Value Type='Text'>" + strCustomerName + "</Value></Contains></Where>";
                        listItemsMain = GetItemsFromCAMLQuery(listMain, strWhere);
                        break;
                    default:
                        throw new Exception("存在しないSearchTypeです。SearchType=" + searchType.ToString());
                        break;
                }

                //全件検索(SP.CamlQuery)
                //検索キーワードを含む(SP.CamlQuery)
                clientContext.Load(listItemsMain); //必用?

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        adapter_EventHandler(true, null,searchType, listItemsMain, listItemsSub);
                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), searchType, null, null);
                    })
                );
            }
        }

        ////////////////////////////////////////////////////////////////////////////
        ///  新規追加 or 更新処理
        ////////////////////////////////////////////////////////////////////////////
        private Adapter_EventHandler<int> _AsyncUpload_Sub_adapter_EventHandler = null;
        private bool _AsyncUpload_Sub_IsAddNew;

        protected enum SEQType
        {
            Quotation
        }

        protected void AsyncUpload_Sub(Adapter_EventHandler<int> adapter_EventHandler, bool IsAddNew, int nSEQNo)
        {
            _AsyncUpload_Sub_adapter_EventHandler = adapter_EventHandler;
            _AsyncUpload_Sub_IsAddNew = IsAddNew;

            if (IsAddNew)
            {
                AsyncUpload_Sub_AddNew(adapter_EventHandler);
            }
            else
            {
                AsyncUpload_Sub_Update(nSEQNo);
            }
        }

        private const  int LIST_LOCKTABLE_SEQNO = 0;
        private const int LIST_SEQNO_START_SEQNO = 1;

        private void AsyncUpload_Sub_AddNew(Adapter_EventHandler<int> adapter_EventHandler)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.List listSEQNo = null;
                SP.List listLock = null;

                SP.ListItemCollection listItemsSEQNo = null;
                SP.ListItemCollection listItemsLock = null;

                string strWhere = string.Empty;
                string strOrderBy = string.Empty;

                string strListSEQNo = "List_SEQNo";
                string strListLock = _strListLock;

                listSEQNo = clientContext.Web.Lists.GetByTitle(strListSEQNo);
                listLock = clientContext.Web.Lists.GetByTitle(strListLock);

                //疑似行ロックする。
                {
                    SP.ListItem li = null;
                    li = listLock.AddItem(new SP.ListItemCreationInformation());
                    //行更新
                    li["SEQNo"] = LIST_LOCKTABLE_SEQNO;
                    li.Update();
                }

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        //SEQNoを取得する。
                        strWhere = GetWhere_SEQNo(_nListSEQNo_SEQNo);
                        listItemsSEQNo = GetItemsFromCAMLQuery(listSEQNo, strWhere);
                        clientContext.Load(listItemsSEQNo);

                        //ロックテーブルを取得する。
                        strWhere = GetWhere_SEQNo(LIST_LOCKTABLE_SEQNO);
                        listItemsLock = GetItemsFromCAMLQuery(listLock, strWhere);
                        clientContext.Load(listItemsLock);

                        clientContext.ExecuteQueryAsync(
                            new SP.ClientRequestSucceededEventHandler(delegate(object o2, SP.ClientRequestSucceededEventArgs successargs2)
                            {
                                int SEQNo;
                                if(listItemsSEQNo.Count ==0)
                                {
                                    {
                                        SP.ListItem li = null;
                                        li = listSEQNo.AddItem(new SP.ListItemCreationInformation());
                                        //行更新
                                        li["SEQNo"] = _nListSEQNo_SEQNo;
                                        SEQNo = LIST_SEQNO_START_SEQNO;
                                        li["SEQNoMain"] = SEQNo;
                                        li.Update();
                                    }
                                }
                                else
                                {
                                    //SEQNoに +1する。
                                    SEQNo = Static_Common.ListItemToInt(listItemsSEQNo[0]["SEQNoMain"]);
                                    SEQNo++;
                                    listItemsSEQNo[0]["SEQNoMain"] = SEQNo;
                                    listItemsSEQNo[0].Update();
                                }

                                //ロックテーブル削除する。
                                DeleteAllItems(listLock, listItemsLock);

                                clientContext.ExecuteQueryAsync(
                                    new SP.ClientRequestSucceededEventHandler(delegate(object o3, SP.ClientRequestSucceededEventArgs successargs3)
                                    {
                                        //SEQNo作成成功
                                        AsyncUpload_Sub_Update(SEQNo);
                                    }),
                                    new SP.ClientRequestFailedEventHandler(delegate(object o3, SP.ClientRequestFailedEventArgs failedArgs3)
                                    {
                                        adapter_EventHandler(false, new Exception(failedArgs3.ErrorDetails + "   " + failedArgs3.Message), int.MinValue);
                                    })
                                );
                            }),
                            new SP.ClientRequestFailedEventHandler(delegate(object o2, SP.ClientRequestFailedEventArgs failedArgs2)
                            {
                                adapter_EventHandler(false, new Exception(failedArgs2.ErrorDetails + "   " + failedArgs2.Message), int.MinValue);
                            })
                        );

                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {

                        //ロックできなかった。

                        //今後の改善ポイント
                        // ロックテーブルが5分以上ふるかったらありえないので強制的に削除する。
                        // その後リトライする。

                        //とりあえず今はユーザにメッセージを返すだけにする。
                        adapter_EventHandler(false, new Exception("連番作成時(SEQNo)に行ロック(疑似)できませんでした。しばらくして再度実行してください。"), int.MinValue);

                    })
                );

            }
        }

        private void AsyncUpload_Sub_Update(int nSEQNo)
        {
            AsyncUpload_Sub_Sub(_AsyncUpload_Sub_adapter_EventHandler, _AsyncUpload_Sub_IsAddNew, nSEQNo);
        }
        private void AsyncUpload_Sub_Sub(Adapter_EventHandler<int> adapter_EventHandler, bool IsAddNew, int nSEQNo)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.List listMain = null;
                SP.List listSub = null;

                SP.ListItemCollection listItemsMain = null;
                SP.ListItemCollection listItemsSub = null;

                string strWhere = string.Empty;
                string strOrderBy = string.Empty;

                listMain = clientContext.Web.Lists.GetByTitle(_strListMain);

                if (!string.IsNullOrEmpty(_strListSub))
                {
                    listSub = clientContext.Web.Lists.GetByTitle(_strListSub);
                }

                //新規or更新
                {
                    if (IsAddNew)
                    {
                    }
                    else
                    {
                        //取得
                        {
                            strWhere = GetWhere_SEQNo(nSEQNo);
                            listItemsMain = GetItemsFromCAMLQuery(listMain, strWhere);
                            clientContext.Load(listItemsMain); //IDを取るのに必要?
                        }

                        //明細行取得
                        if (!string.IsNullOrEmpty(_strListSub))
                        {
                            strWhere = GetWhere_PersonSEQNo(nSEQNo);
                            listItemsSub = GetItemsFromCAMLQuery(listSub, strWhere);
                            clientContext.Load(listItemsSub); //明細をとるのに必要?
                        }
                    }
                }

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        AsyncUpload_Sub_OnSetValue(nSEQNo, IsAddNew, listMain, listSub, listItemsMain, listItemsSub);

                        clientContext.ExecuteQueryAsync(
                                new SP.ClientRequestSucceededEventHandler(delegate(object o3, SP.ClientRequestSucceededEventArgs successargs3)
                                {
                                    adapter_EventHandler(true, null, nSEQNo);

                                }),
                                new SP.ClientRequestFailedEventHandler(delegate(object o3, SP.ClientRequestFailedEventArgs failedArgs)
                                {
                                    adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), nSEQNo);
                                }));
                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), 0);
                    }));
            }
        }

        protected virtual void AsyncUpload_Sub_OnSetValue(int nSEQNo, bool IsAddNew, SP.List listMain, SP.List listSub, SP.ListItemCollection listItemsMain , SP.ListItemCollection listItemsSub)
        {
        }

        ////////////////////////////////////////////////////////////////////////////
        ///  削除処理
        ////////////////////////////////////////////////////////////////////////////
        protected void AsyncDelete(Adapter_EventHandler adapter_EventHandler, int nSEQNo, string strListDocName)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.List listMain = null;
                SP.List listSub = null;

                SP.ListItemCollection listItemsMain = null;
                SP.ListItemCollection listItemsSub = null;

                string strWhere = string.Empty;
                string strOrderBy = string.Empty;

                listMain = clientContext.Web.Lists.GetByTitle(_strListMain);
                listItemsMain = null;
                //削除処理
                strWhere = GetWhere_SEQNo(nSEQNo);
                listItemsMain = GetItemsFromCAMLQuery(listMain, strWhere);
                clientContext.Load(listItemsMain); //明細をとるのに必要?

                //明細行取得
                if (!string.IsNullOrEmpty(_strListSub))
                {
                    listSub = clientContext.Web.Lists.GetByTitle(_strListSub);
                    listItemsSub = null;
                    strWhere = GetWhere_PersonSEQNo(nSEQNo);
                    listItemsSub = GetItemsFromCAMLQuery(listSub, strWhere);
                    clientContext.Load(listItemsSub); //明細をとるのに必要?
                }

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        try
                        {
                            //削除
                            if (null != listMain)
                            {
                                DeleteAllItems(listMain, listItemsMain);
                            }

                            //明細行削除
                            if (null != listSub)
                            {
                                DeleteAllItems(listSub, listItemsSub);
                            }

                            clientContext.ExecuteQueryAsync(
                                    new SP.ClientRequestSucceededEventHandler(delegate(object o3, SP.ClientRequestSucceededEventArgs successargs3)
                                    {
                                        try
                                        {
                                            if (string.IsNullOrEmpty(_strListMain))
                                            {
                                                adapter_EventHandler(true, null);
                                            }
                                            else
                                            {
                                                Adapter_Base_DocumentLibrary.AsyncDelete(
                                                    new Adapter_EventHandler<int>(delegate(bool IsSuccess, Exception e2, int nCount)
                                                    {
                                                        adapter_EventHandler(IsSuccess, e2);

                                                    }),
                                                    _strListDoc,
                                                    strListDocName
                                                    );
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            adapter_EventHandler(false, ex);
                                        }
                                    }),
                                    new SP.ClientRequestFailedEventHandler(delegate(object o3, SP.ClientRequestFailedEventArgs failedArgs)
                                    {
                                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message));
                                    }));
                        }
                        catch (Exception ex2)
                        {
                            adapter_EventHandler(false, ex2);
                        }

                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message));
                    })
                );
            }
        }
    }

}

SharePointで伝票形式(ヘッダー、行)を複数(Multiple)のListで作るときの最適なキー(sequential number auto generator)の持ち方。(Silverlight, C#, List)

SharePointには自動的に連番になる[ID]というのがありますが、異なるサイトにデータ移行するときに新しい連番で採番されてしまします。

([テンプレート保存]で移行すればIDはそのまま移行できる。)

IDをベースとしてほかのリストとにのリレーションしていると、ほかのリストのリレーションを更新しないといけなくなります。

IDをベースとしないアプリケーション作成をお勧めします。以下に例をのせておきます。

例)見積アプリケーションの場合

以下のような ヘッダー・明細構造にしてSEQNoとPersonSEQNoでリレーションをします。そうするとリストデータを他のサイトに移行しても番号がずれる等の問題を防ぐことができます。

次の投稿で重複しない、連番のとりかた(SEQNo)は説明します。

見積(ヘッダー)リスト

ID SEQNo TITLE その他項目
1 10001 Title10001 Other10001
2 10002 Title10002 Other10002

見積明細リスト

ID PersonSEQNo TITLE その他項目
1 10001    
2 10001    
3 10002    
4 10002    

List_Quotation – Shmea.xml (見積ヘッダー)
28行目のように検索するときに重要な項目は以下のように設定してください。

  1. 必須:Required=”TRUE”
  2. ユニーク:EnforceUniqueValues=”TRUE”
  3. インデックス:Indexed=”TRUE”
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="List_Quotation" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/List_Quotation" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100529434ab8e0a4fd48a973ccfcd48a293" Name="ListFieldsContentType">
        <FieldRefs>
          <FieldRef ID="{43bcd793-3e7b-4ec5-8dbd-d35ff4786700}" Name="SEQNo" />
          <FieldRef ID="{e0e936a2-a2ac-4cac-b617-9332035bca63}" Name="Memo" />
          <FieldRef ID="{13b6ce57-22a1-4d99-89ab-64006458342b}" Name="InvoiceID" />
          <FieldRef ID="{d90001da-42fd-43f4-9d81-52f4116ead4c}" Name="Subject1" />
          <FieldRef ID="{45dedcec-9c80-4e4c-a929-635976b7a1b9}" Name="Subject2" />
          <FieldRef ID="{51fb32b7-a01b-461e-ac33-6d65b0a3ac9d}" Name="CreateDate" />
          <FieldRef ID="{7e1e3c7a-2d07-45f9-bb3c-e68c9513cca2}" Name="Other1" />
          <FieldRef ID="{a9df7ffc-0604-4ced-a9a9-4273b3f14e5a}" Name="Other2" />
          <FieldRef ID="{f4777239-7f59-4f81-9769-7ea956f5c8be}" Name="CustomerName" />
          <FieldRef ID="{9dd95fa6-3811-409b-b762-2e0380d917a2}" Name="ConsumptionTax" />
          <FieldRef ID="{251e0a26-2011-4e2d-a13d-5283868b8dba}" Name="TotalAmount" />
          <FieldRef ID="{bd132826-132d-4e35-95ee-ca9ae795bf06}" Name="SubTotal" />
          <FieldRef ID="{8494697b-7d50-4fdf-a257-07452fc54f08}" Name="Approved" />
        </FieldRefs>
      </ContentType>
      <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
    </ContentTypes>
    <Fields>
      <Field Name="SEQNo" ID="{43bcd793-3e7b-4ec5-8dbd-d35ff4786700}" DisplayName="SEQNo" Type="Number" Required="TRUE" EnforceUniqueValues="TRUE" Indexed="TRUE" />
      <Field Name="Memo" ID="{e0e936a2-a2ac-4cac-b617-9332035bca63}" DisplayName="Memo" Type="Note" />
      <Field Name="InvoiceID" ID="{13b6ce57-22a1-4d99-89ab-64006458342b}" DisplayName="InvoiceNo" Type="Text" />
      <Field Name="Subject1" ID="{d90001da-42fd-43f4-9d81-52f4116ead4c}" DisplayName="Subject1" Type="Text" />
      <Field Name="Subject2" ID="{45dedcec-9c80-4e4c-a929-635976b7a1b9}" DisplayName="Subject2" Type="Text" />
      <Field Name="CreateDate" ID="{51fb32b7-a01b-461e-ac33-6d65b0a3ac9d}" DisplayName="CreateDate" Type="DateTime" />
      <Field Name="Other1" ID="{7e1e3c7a-2d07-45f9-bb3c-e68c9513cca2}" DisplayName="Other1" Type="Text" />
      <Field Name="Other2" ID="{a9df7ffc-0604-4ced-a9a9-4273b3f14e5a}" DisplayName="Other2" Type="Text" />
      <Field Name="CustomerName" ID="{f4777239-7f59-4f81-9769-7ea956f5c8be}" DisplayName="CustomerName" Type="Text" Indexed="TRUE" />
      <Field Name="ConsumptionTax" ID="{9dd95fa6-3811-409b-b762-2e0380d917a2}" DisplayName="ConsumptionTax" Type="Currency" />
      <Field Name="TotalAmount" ID="{251e0a26-2011-4e2d-a13d-5283868b8dba}" DisplayName="TotalAmount" Type="Currency" />
      <Field Name="SubTotal" ID="{bd132826-132d-4e35-95ee-ca9ae795bf06}" DisplayName="SubTotal" Type="Text" />
      <Field Name="Approved" ID="{8494697b-7d50-4fdf-a257-07452fc54f08}" DisplayName="Approved" Type="Boolean" />
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="ID" />
          <FieldRef Name="SEQNo" />
          <FieldRef Name="Title" />
          <FieldRef Name="InvoiceID" />
          <FieldRef Name="Subject1" />
          <FieldRef Name="Subject2" />
          <FieldRef Name="CreateDate" />
          <FieldRef Name="Other1" />
          <FieldRef Name="Other2" />
          <FieldRef Name="CustomerName" />
          <FieldRef Name="ConsumptionTax" />
          <FieldRef Name="TotalAmount" />
          <FieldRef Name="SubTotal" />
          <FieldRef Name="Approved" />
          <FieldRef Name="Memo" />
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

List_QuotationSub – Shmea.xml (見積明細)
24行目のように検索するときに重要な項目は以下のように設定してください。

  1. 必須:Required=”TRUE”
  2. ユニーク:EnforceUniqueValues=”TRUE”
  3. インデックス:Indexed=”TRUE”
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="List_QuotationSub" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/List_QuotationSub" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100f22a3e8a340e4db5a75ec11dcebcb6c1" Name="ListFieldsContentType">
        <FieldRefs>
          <FieldRef ID="{31a30adb-6937-4393-b39e-be73b3a9bc3e}" Name="PersonSEQNo" />
          <FieldRef ID="{64d09fd6-bdb9-43fe-a517-3172198755ae}" Name="No" />
          <FieldRef ID="{91f6f42b-f97f-44a1-9168-2a084858491d}" Name="Desc01" />
          <FieldRef ID="{d67bc5f8-c6a5-440b-9b49-89d1dd9fa3a4}" Name="Quantity" />
          <FieldRef ID="{61f2b0f2-35e4-4a5c-9062-85c1edc69608}" Name="unit" />
          <FieldRef ID="{84503137-38a8-41bb-8aee-0ca21b8e1461}" Name="StandardPrice" />
          <FieldRef ID="{f5e0749b-ef36-48c2-87ca-a51cc69b9ac6}" Name="SalesPrice" />
          <FieldRef ID="{8b7ddc42-b1da-45c1-8adf-ec54a7c5a32b}" Name="Amount" />
          <FieldRef ID="{208e12fd-833b-429a-b234-a6e1eedd236d}" Name="Memo" />
        </FieldRefs>
      </ContentType>
      <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
    </ContentTypes>
    <Fields>
      <Field Name="PersonSEQNo" ID="{31a30adb-6937-4393-b39e-be73b3a9bc3e}" DisplayName="PersonSEQNo" Type="Number" Required="TRUE" Indexed="TRUE" />
      <Field Name="No" ID="{64d09fd6-bdb9-43fe-a517-3172198755ae}" DisplayName="No" Type="Number" Indexed="TRUE" />
      <Field Name="Desc01" ID="{91f6f42b-f97f-44a1-9168-2a084858491d}" DisplayName="Desc01" Type="Text" />
      <Field Name="Quantity" ID="{d67bc5f8-c6a5-440b-9b49-89d1dd9fa3a4}" DisplayName="Quantity" Type="Number" />
      <Field Name="unit" ID="{61f2b0f2-35e4-4a5c-9062-85c1edc69608}" DisplayName="unit" Type="Text" />
      <Field Name="StandardPrice" ID="{84503137-38a8-41bb-8aee-0ca21b8e1461}" DisplayName="StandardPrice" Type="Currency" />
      <Field Name="SalesPrice" ID="{f5e0749b-ef36-48c2-87ca-a51cc69b9ac6}" DisplayName="SalesPrice" Type="Currency" />
      <Field Name="Amount" ID="{8b7ddc42-b1da-45c1-8adf-ec54a7c5a32b}" DisplayName="Amount" Type="Currency" />
      <Field Name="Memo" ID="{208e12fd-833b-429a-b234-a6e1eedd236d}" DisplayName="Memo" Type="Text" />
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="ID" />
          <FieldRef Name="SEQNo" />
          <FieldRef Name="Title" />
          <FieldRef Name="No" />
          <FieldRef Name="Desc01" />
          <FieldRef Name="Quantity" />
          <FieldRef Name="unit" />
          <FieldRef Name="StandardPrice" />
          <FieldRef Name="SalesPrice" />
          <FieldRef Name="Amount" />
          <FieldRef Name="Memo" />
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

Office365でSilverlightを動かしてみる #コーディング編

Office365のSharePoint Online(以降、SPO)では、サンドボックス ソリューションしか動作しないので簡単な
アプリを作って実装してみたいと思います。
Silverlightを使ったVideoアプリを作ってみましょう。
たぶん、簡単なはず…w

主な開発環境
・SharePoint Foundation
・Windows Server 2008 R2 64bit
・Visual Studio 2012 Proffesional

※詳細は、「Office365(Sharepoint)開発環境について」を参考にしてください。

1. Visual Studio 2012を起動して、プロジェクトを作成します。
  ここで「ファイル」→「新規作成(N)」→「プロジェクト(P)」を選択します。
  

2. 今回のコーディングはC#を使いますので、左のメニューから「インストール済」→「テンプレート」→「Visual C#」→
  「SharePoint」→「2010」を選択します。
  そうすると中央にプロジェクトやパーツメニューが表示されます。
  その中から「SharePoint 2010 Silverlight Webパーツ」を選択します。
  

3. 次にセキュリティレベルの指定画面が表示されます。
  ローカルサイトはデフォルトで表示されるので、とく変更する必要はありません。
  ソリューションの信頼レベルですが、サンドボックスなので「サンドボックス ソリューションとして配置する(B)」を
  選択します。
  ※ファームはOffice365では動作しません
  

4. 次に構成情報の指定画面が表示されます。
  基本、そのまま「完了」でOKです。
  

5. これでひととおりの設定が終わったのでプロジェクトおよびソリューションが構成されて画面が表示されます。
  

6. 「MainPage.xaml」というファイルがあります。
  これがSilverlightの表示部(画面?と言ったほうがいいのか)になります。
  デザイン部分とコード部分に分かれて表示されています。
  デフォルトでは、枠だけの状態です。

  【デザイン部】
  

  枠の左端にカーソルを移動するとオレンジ色になります。
  そこでクリックするとGridを分割することができます。
  とりあえず、URL部分(Grid.Row=1)、Video部分(Grid.Row=2)、ボタン部分(Grid.Row=3)に分割してみました。

  【コード部】
  

  ・青枠の部分は、Gridを分けたときのそれぞれの高さを表記しています。
   「*」にすると自動調整するようです。(細かいところは分かりません)
  ・赤枠の部分は、Gridを分けたときにタグが自動生成されます。
   注)Gridタグ内にある「Grid.Row」を必ず重複しないように設定してください。

  そんなこんなで画面にパーツを配置していきます。
  左端にある「ツールボックス」を開いて以下の部品を配置します。
  

  Grid.Row=1
   ・Label×1 →「URL」
   ・TextBox×1

  Grid.Row=2
   Videoパーツを追加するため部品は配置しません
   その代り、Videoパーツをコード上で追加するため、名前をつけておきます。
   名前は何でもいいのですが、ここでは「LayoutVideo」とつけておきましょう。

  Grid.Row=3
   ・Button×3 →「Play」、「Pause」、「Stop」
   
   部品の名前は分かり易いような名前がいいですね。

7. 「MainPage.xaml」の編集が終わったら、C#コード「MainPage.xaml.cs」を編集しましょう。
  赤枠の部分を追記していきます。
  イベントは「MainPage.xaml」で配置したボタンのプロパティから追加できますし、ボタンをダブルクリックしても
  自動生成できますのでお好みでどうぞ。
  

  ※ボタンのプロパティ
  

【MainPage.xaml.cs】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace EAP_Office365_Patrs_SilverlightVideo
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private MediaElement _media_element;

        // Event
        // Playボタンが押された
        private void Button_Play_Click(object sender, RoutedEventArgs e)
        {
            if (this.Text_Url.Text != "")
            {
                this._media_element = new MediaElement();
                this._media_element.Source = new Uri(this.Text_Url.Text);   // Videoソース
                this._media_element.AutoPlay = true;                        // 自動再生ON/OFF
                this._media_element.Width = 320;                            // Video枠(横幅)
                this._media_element.Height = 240;                           // Video枠(縦幅)

                this.LayoutVideo.Children.Add(this._media_element);         // SilverlightにVideoを追加
            }
        }

        // Event
        // Pauseボタンが押された
        private void Button_Pause_Click(object sender, RoutedEventArgs e)
        {
            if (this._media_element.CurrentState == MediaElementState.Paused)
            {
                // Video再生
                this._media_element.Play();
            }
            else
            {
                // Video一時停止
                this._media_element.Pause();
            }
        }

        // Event
        // Stopボタンが押された
        private void Button_Stop_Click(object sender, RoutedEventArgs e)
        {
            // Video停止
            this._media_element.Stop();
        }
    }
}

これでコーディングは完了です。
初回なのでコードはシンプルにしました。

「Office365でSilverlightを動かしてみる #実装編」にてOffice365(SharePoint Online)へ実装します。

WebTemplateの作り方(Sharepoint Online(Office365))

はじめに

SharePointのサイトを配布する方法には、

WebTemplate(ウェブテンプレート) と Site Definition(サイト定義)があります。

SharePoint Online(Office365) ですとWebTemplateしか使えません。

今回はWebTemplate(ウェブテンプレート)の作り方について解説します。

 

WebTempalte(とSite Definition)とは

以下のように[サイトの操作]-[新しいサイト]をクリックしたときにでてくるウェブテンプレートもしくはサイト定義のことです。

Visual Studioで作成する方法

必要なものをVisualStudioに配置します。(Visaul Studio2012の場合)

モジュールにイメージを作成します。

Element.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="images">
  <File Path="images\EAPApplication.png" Url="images/EAPApplication.png" IgnoreIfAlreadyExists="TRUE"/>
</Module>
</Elements>

モジュールにWebTemplateを作成します。

Element.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <WebTemplate Name="EAPApplication"
               ImageUrl="/images/EAPApplication.png"
               Title="EAP_Office365 V1.0.0"
               BaseTemplateID="1"
               BaseTemplateName="STS"
               BaseConfigurationID="0"
               DisplayCategory="EAP" />
</Elements>

ONET.XML

<?xml version="1.0" encoding="utf-8"?>
<Project Title="EAP_Office365 V1.0.0" Revision="1" ListDir="" xmlns:ows="Microsoft SharePoint" UIVersion="4">
  <NavBars></NavBars>
  <ListTemplates></ListTemplates>
  <Configurations>
    <Configuration ID="0" Name="EAP_Office365 V1.0.0">
      <Lists></Lists>
      <Modules>
        <Module Name="DefaultBlank" />
      </Modules>
      <SiteFeatures>
        <!-- BasicWebParts Feature -->
        <!-- <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />-->
        <!-- SharePoint Server Standard Site Collection Features -->
        <!-- <Feature ID="b21b090c-c796-4b0f-ac0f-7ef1659c20ae" />-->
        <!-- SharePoint Server Enterprise Site Collection Features -->
        <!-- <Feature ID="8581a8a7-cf16-4770-ac54-260265ddb0b2" />-->
        <!-- Document Sets つかえない参考http://sharepintblog.com/2011/06/01/activating-features-in-a-site-subscription-feature-pack/ -->
        <!--<Feature ID="3bae86a2-776d-499d-9db8-fa4cdc7884f8" />-->
        <!-- Register Taxonomy (Required for Enterprise Keywords Field) -->
        <!-- <Feature ID="73ef14b1-13a9-416b-a9b5-ececa2b0604c" />-->
        <!-- Publishing PreReqs/Resources (Required for Target Audience Field) -->
        <!-- <Feature ID="A392DA98-270B-4e85-9769-04C0FDE267AA" />-->
        <!-- <Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E" />-->
      </SiteFeatures>
      <WebFeatures>
        <!-- TeamCollab Feature -->
        <!--<Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />-->
        <!-- MobilityRedirect -->
        <!--Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />-->
        <!-- SharePoint Server Standard Site Features -->
        <!--<Feature ID="99fe402e-89a0-45aa-9163-85342e865dc8" />-->
        <!-- SharePoint Server Enterprise Site Features -->
        <!--<Feature ID="0806d127-06e6-447a-980e-2e90b03101b8" />-->
        <Feature ID="6647f0e1-8988-4cd3-bec0-ab379085655c" />

      </WebFeatures>
    </Configuration>
  </Configurations>
  <Modules>
    <Module Name="DefaultBlank" Url="" Path="">
      <File Url="default.aspx">
      </File>
    </Module>
  </Modules>
</Project>

サイトレベルのフューチャーに登録します。

マニフェスト

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Id="d753a14e-330f-4a86-92fe-07a47d70dcf6" Scope="Site" Title="Feature_Site">
  <ElementManifests>
    <ElementManifest Location="EAPApplication\Elements.xml" />
    <ElementFile Location="EAPApplication\ONET.XML" />
    <ElementManifest Location="SilverlightWebPartMain\Elements.xml" />
    <ElementFile Location="SilverlightWebPartMain\SilverlightWebPartMain.webpart" />
    <ElementFile Location="SilverlightWebPartMain\SilverlightProjectMain.xap" />
    <ElementFile Location="images\EAPApplication.png" />
    <ElementManifest Location="images\Elements.xml" />
  </ElementManifests>
</Feature>

以上でWebTemplate作成できました!

今から始めるSharePoint Online開発

私は、SharePoint開発が全バージョンを含めて初めてなので、初歩的な記事から書かせていただきます。
これからSharePoint Online開発を始めようとする方、興味のある方、参考にしていただければ幸いです。
間違った記事書いたらゴメンなさい。。。

まず、”SharePoint”ですが、端的に言えば「グループウェア」です。
ドキュメントの共有等ができます。
【SharePont Foundation】、【SharePont Server】、【SharePoint Online】の3つ種類があります。

  【SharePoint Foundation】
   Microsoftが無償提供しているサーバー製品です。
   社内設置型で、自社サーバを用意して環境を構築する必要があります。
   以前までは、「Windows SharePoint Services(WSS)」と呼ばれていました。
   開発環境として利用することが可能。

  【SharePoint Server】
   Microsoftが提供しているサーバー製品です。
   社内設置型で、自社サーバを用意して環境を構築する必要があります。

  【SharePoint Online】
   Microsoftによってホストされるクラウドサービス【Office365】を構成するサービスのひとつです。
   クラウドサービスなので自社サーバ構築が不要。
   ブラウザがあれば利用可能です。

   詳しくは、Office365Roomにて紹介しています。
   http://www.office365room.com/

参考URL
SharePointとは何か
http://office.microsoft.com/ja-jp/sharepoint-foundation-help/HA010378184.aspx

エディション別機能比較ガイド(SharePoint Foundation/SharePoint Server/SharePoint Online)
http://www.microsoft.com/ja-jp/download/details.aspx?id=27145

SharePointも色々ありますねーと思いつつ、Office365のサービスでもあるSharePoint Onlineに向けた開発について勉強しながら書いていきましょう。

Silverlight Page, ChildWindowの画面をひらいたときにフォーカスを設定する方法(Silverlight, C#)

アプリケーションの画面をひらいたときにフォーカスを指定したい場合がありますが、その場合はSilverlightでは以下のようにします。

ナビゲーションページの場合

TestPage(ナビゲーションページ)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace SilverlightProjectMain
{
    public partial class TestPage : Page
    {
        public Testpage()
        {
            InitializeComponent();
        }

        // ユーザーがこのページに移動したときに実行されます。
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.textboxCustomer.UpdateLayout();
            this.textboxCustomer.Focus();
        }
    }
}

チャイルドウインドウの場合

TestChildWindow(チャイルドウインドウ)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightProjectMain
{
    public partial class TestChildWindow : ChildWindow
    {
        public TestChildWindow()
        {
            InitializeComponent();
            this.GotFocus += this.Event_GotFocus;
            controlFirstFocus = textboxInvoiceID;
        }

        protected Control controlFirstFocus=null;
        private bool IsFirstCall = true;

        private void Event_GotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.IsFirstCall)
            {
                if (null != controlFirstFocus)
                {
                    controlFirstFocus.Focus();
                }
                this.IsFirstCall = false;
            }
        }
    }
}

SharePoint Dialogの使い方(Client Object Model, Sharepoint Online(Office365), JavaScript)

SharePointの標準のダイアログを表示する方法です。

以下のボタンをおしたときにSharePointの標準のダイアログを呼び出します。

独自のaspxがSharePointダイアログの中に表示されます。

[OK]ボタンをおします。

ボタンを押したときに引数を送れますのでその内容を表示します。

default.aspx

<%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"  %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<asp:Content ID="phPageTitle" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
    <SharePoint:ProjectProperty ID="ppTitle" Property="Title" runat="server"/>
</asp:Content>

<asp:Content ID="phMain" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<script type="text/javascript">
    function ShowDialog() {
        var options = SP.UI.$create_DialogOptions();
        options.title = "Test Dialog"
        options.url = "EAP_Resources/Test/ShowDialog.aspx";
        options.autoSize = true;
        options.width = 500;
        options.height = 300;
        options.dialogReturnValueCallback = Function.createDelegate(null, CloseCallback);
        SP.UI.ModalDialog.showModalDialog(options);
    }

    function CloseCallback(result, target) {
        alert(target);
        if (result === SP.UI.DialogResult.OK) {
            //SP.UI.Notify.addNotification("OK Clicked");
        }
        else if (result === SP.UI.DialogResult.cancel) {
            //SP.UI.Notify.addNotification("Cancelled Clicked");
        }
    }
</script>

<input type="button" value="Test Dialog(Sharepoint)" onClick="ShowDialog()">

</asp:Content>

ShowDialog.aspx

<%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"  %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<asp:Content ID="phPageTitle" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
    <SharePoint:ProjectProperty ID="ppTitle" Property="Title" runat="server"/>
</asp:Content>

<asp:Content ID="phMain" ContentPlaceHolderId="PlaceHolderMain" runat="server">
    <%--リボンを消す--%>
    <style type="text/css">  
        body{overflow:auto !important;}
        #s4-leftpanel { display: none;}
        .s4-ca {margin-left:0px !important;}
        #s4-ribbonrow{height:auto !important;min-height:0px !important;}
        #s4-ribboncont{display:none;}
        #s4-titlerow{ display:none;}
        .s4-ba {width:100%; min-height:0px !important;}
        #s4-workspace{float:left;width:100%; overflow:auto  !important;}
        body #MSO_ContentTable{min-height:0px !important;position:inherit;}
    </style>

    <script type="text/javascript"> 
        function Ok_Click() 
        { 
            SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, 'OK Clicked(args)');
        } 

        function Cancel_Click() 
        { 
            SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel, 'Cancelled Clicked(args)'); 
        } 
</script>

<input type="button" value="OK" onClick="Ok_Click()">
<input type="button" value="Cancel" onClick="Cancel_Click()">

</asp:Content>

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="Test" Url="EAP_Resources">
  <File Path="Test\ShowDialog.aspx" Url="Test/ShowDialog.aspx" />
</Module>
</Elements>

メモ

IE9のみしか確認していませんが、Silverlightから以下のようにJavaScript経由で呼び出すことはできるのですが、

HtmlPage.Window.Invoke(“ShowDialog”);

ダイアログを閉じたときにSilverlightのReload(再読み込み)が走り、Silverlightのアプリは初期画面になります。

その他参考

Waitダイアログ:http://blog.collabware.com/tag/sp-ui-modaldialog/

ダイアログをJavaScriptで閉じる:http://dbarrowstechblog.blogspot.jp/2011/06/close-sharepoint-modal-dialog-from.html

2つ以上のList更新する方法(Client Object Model, Sharepoint Online(Office365), Silverlight, C#)

2つ以上のListの更新をする場合や削除してから追加する場合は少し複雑になりますのでサンプルを作ってみました。

以下の画面から検索ボタン(検索処理)を押したときの処理

以下の画面から保存ボタン(更新処理)、アイテム削除ボタン(削除処理)

削除処理、検索処理、更新処理のクラスです。

Adapter_CQuotation.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using SP = Microsoft.SharePoint.Client;
using System.Collections.ObjectModel;

using System.Xml.Serialization;
using SilverlightProjectMain.Models.SharepointClient.Base;

namespace SilverlightProjectMain.Models.SharepointClient
{

    public class Adapter_CQuotation : Adapter_Base0100
    {
        ////////////////////////////////////////////////////////////////////////////
        ///  削除処理
        ////////////////////////////////////////////////////////////////////////////
        static public void AsyncDelete(Adapter_EventHandler adapter_EventHandler, int nID)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                var list = clientContext.Web.Lists.GetByTitle("List_Quotation");
                //clientContext.Load(list);

                //削除処理
                SP.ListItem listItem = list.GetItemById(nID);
                listItem.DeleteObject();

                SP.ListItemCollection listItemsDetail = null;

                //明細行取得
                var listDetail = clientContext.Web.Lists.GetByTitle("List_QuotationDetail001");
                string strWhere = "<Where><Eq><FieldRef Name='PersonID' /><Value Type='Integer'>" + nID.ToString() + "</Value></Eq></Where>";
                listItemsDetail = GetItemsFromCAMLQuery(listDetail, strWhere);
                clientContext.Load(listItemsDetail);

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        try
                        {
                            //明細行削除
                            {
                                foreach (var li in listItemsDetail)
                                {
                                    SP.ListItem item = listDetail.GetItemById(li.Id);
                                    item.DeleteObject();
                                }
                            }

                            clientContext.ExecuteQueryAsync(
                                    new SP.ClientRequestSucceededEventHandler(delegate(object o3, SP.ClientRequestSucceededEventArgs successargs3)
                                    {
                                        adapter_EventHandler(true, null);
                                    }),
                                    new SP.ClientRequestFailedEventHandler(delegate(object o3, SP.ClientRequestFailedEventArgs failedArgs)
                                    {
                                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message));
                                    }));
                        }
                        catch (Exception ex2)
                        {
                            adapter_EventHandler(false, ex2);
                        }

                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message));
                    })
                );
            }
        }

        ////////////////////////////////////////////////////////////////////////////
        ///  取得処理
        ////////////////////////////////////////////////////////////////////////////
        //IDで検索(SPList.GetItemById)
        static public void AsyncDownload(Adapter_EventHandlerCollection<CQuotation, CQuotationDetail001> adapter_EventHandler, int nID)
        {
            AsyncDownload_Sub(adapter_EventHandler, SearchType.ID, nID, string.Empty);
        }

        //全件検索(SP.CamlQuery)
        static public void AsyncDownload(Adapter_EventHandlerCollection<CQuotation, CQuotationDetail001> adapter_EventHandler)
        {
            AsyncDownload_Sub(adapter_EventHandler, SearchType.All, int.MinValue, string.Empty);
        }

        //検索キーワードを含む(SP.CamlQuery)
        static public void AsyncDownload(Adapter_EventHandlerCollection<CQuotation, CQuotationDetail001> adapter_EventHandler, string strCustomerName)
        {
            AsyncDownload_Sub(adapter_EventHandler, SearchType.Type001, int.MinValue, strCustomerName);
        }

        static private void AsyncDownload_Sub(Adapter_EventHandlerCollection<CQuotation, CQuotationDetail001> adapter_EventHandler, SearchType searchType, int nID, string strCustomerName)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.List list = clientContext.Web.Lists.GetByTitle("List_Quotation");
                SP.List listDetail = null;

                //load不要
                //clientContext.Load(list);

                SP.ListItem listItem = null;
                SP.ListItemCollection listItems = null;

                SP.ListItemCollection listItemsDetail = null;

                string strWhere = string.Empty;
                string strOrderBy = string.Empty;

                switch (searchType)
                {
                    //IDで検索(SPList.GetItemById)
                    case SearchType.ID:
                        listItem = list.GetItemById(nID);

                        //明細行取得
                        listDetail = clientContext.Web.Lists.GetByTitle("List_QuotationDetail001");
                        strWhere = "<Where><Eq><FieldRef Name='PersonID' /><Value Type='Integer'>" + nID.ToString() + "</Value></Eq></Where>";
                        strOrderBy = "<OrderBy><FieldRef Name=\"No\"></FieldRef></OrderBy>";
                        listItemsDetail = GetItemsFromCAMLQuery(listDetail, strWhere, strOrderBy);
                        clientContext.Load(listItemsDetail);
                        break;

                    //全件検索(SP.CamlQuery)
                    case SearchType.All:
                        listItems = GetItemsFromCAMLQuery(list);
                        break;

                    //検索キーワードを含む(SP.CamlQuery)
                    case SearchType.Type001:
                        //完全一致;    column =‘SearchWord’
                        //listItems = GetItemsFromCAMLQuery(list, "<Where><Eq><FieldRef Name='CustomerName' /><Value Type='Text'>" + strCustomerName + "</Value></Eq></Where>");

                        //検索キーワードを含む: column like ‘%SearchWord%’
                        strWhere = "<Where><Contains><FieldRef Name='CustomerName' /><Value Type='Text'>" + strCustomerName + "</Value></Contains></Where>";
                        listItems = GetItemsFromCAMLQuery(list, strWhere);
                        break;
                    default:
                        throw new Exception("存在しないSearchTypeです。SearchType=" + searchType.ToString());
                        break;
                }

                if (SearchType.ID == searchType)
                {
                    //IDで検索(SPList.GetItemById)
                    clientContext.Load(listItem);

                }
                else
                {
                    //全件検索(SP.CamlQuery)
                    //検索キーワードを含む(SP.CamlQuery)
                    clientContext.Load(listItems);
                }

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        var oc_CQuotations = new System.Collections.ObjectModel.ObservableCollection<CQuotation>();

                        if (SearchType.ID == searchType)
                        {
                            //IDで検索(SPList.GetItemById)
                            addObservableCollection(oc_CQuotations, listItem);

                            //明細を取得する。
                            var oc_CQuotationDetail001s = new System.Collections.ObjectModel.ObservableCollection<CQuotationDetail001>();

                            //全件検索(SP.CamlQuery)
                            //検索キーワードを含む(SP.CamlQuery)
                            foreach (var li in listItemsDetail)
                            {
                                addObservableCollection(oc_CQuotationDetail001s, li);
                            }

                            adapter_EventHandler(true, null, oc_CQuotations, oc_CQuotationDetail001s);

                        }
                        else
                        {
                            //全件検索(SP.CamlQuery)
                            //検索キーワードを含む(SP.CamlQuery)
                            foreach (var li in listItems)
                            {
                                addObservableCollection(oc_CQuotations, li);
                            }
                            adapter_EventHandler(true, null, oc_CQuotations, null);
                        }
                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), null, null);
                    })
                );
            }

        }

        static private void AsyncDownload_Sub_Detail001(Adapter_EventHandlerCollection<CQuotationDetail001> adapter_EventHandler, int nID)
        {
            try
            {
                using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
                {
                    var list = clientContext.Web.Lists.GetByTitle("List_QuotationDetail001");

                    var strWhere = "<Where><Eq><FieldRef Name='PersonID' /><Value Type='Integer'>" + nID.ToString() + "</Value></Eq></Where>";
                    var strOrderBy = "<OrderBy><FieldRef Name='ID'></FieldRef></OrderBy>";

                    var listItems = GetItemsFromCAMLQuery(list, strWhere, strOrderBy);
                    clientContext.Load(listItems);

                    clientContext.ExecuteQueryAsync(
                        new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                        {
                            try
                            {
                                var oc_CQuotationDetail001s = new System.Collections.ObjectModel.ObservableCollection<CQuotationDetail001>();

                                //全件検索(SP.CamlQuery)
                                //検索キーワードを含む(SP.CamlQuery)
                                foreach (var li in listItems)
                                {
                                    addObservableCollection(oc_CQuotationDetail001s, li);
                                }

                                adapter_EventHandler(true, null, oc_CQuotationDetail001s);
                            }
                            catch (Exception ex2)
                            {
                                adapter_EventHandler(false, ex2, null);
                            }

                        }),
                        new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                        {
                            adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), null);
                        })
                    );
                }
            }
            catch (Exception ex2)
            {
                adapter_EventHandler(false, ex2, null);
            }

        }

        static private void addObservableCollection(System.Collections.ObjectModel.ObservableCollection<CQuotation> oc_CQuotations, SP.ListItem listItem)
        {
            oc_CQuotations.Add(new CQuotation()
            {
                ID = (int)listItem["ID"],
                Approved = (bool)listItem["Approved"],
                InvoiceID = Static_Common.ListItemToString(listItem["InvoiceID"]),
                CustomerName = Static_Common.ListItemToString(listItem["CustomerName"]),
                CreateDate = Static_Common.ListItemToDateTime(listItem["CreateDate"]),
                Subject1 = Static_Common.ListItemToString(listItem["Subject1"]),
                Subject2 = Static_Common.ListItemToString(listItem["Subject2"]),
                Other1 = Static_Common.ListItemToString(listItem["Other1"]),
                Other2 = Static_Common.ListItemToString(listItem["Other2"]),
                Subtotal = Static_Common.ListItemToDecimal(listItem["SubTotal"]),
                ConsumptionTax = Static_Common.ListItemToDecimal(listItem["ConsumptionTax"]),
                TotalAmount = Static_Common.ListItemToDecimal(listItem["TotalAmount"]),
                //RowData = Static_Common.ListItemToString(listItem["RowData"]),
                Memo = Static_Common.ListItemToString(listItem["Memo"]),
            });

        }
        static private void addObservableCollection(System.Collections.ObjectModel.ObservableCollection<CQuotationDetail001> oc_CQuotationDetail001, SP.ListItem listItem)
        {
            oc_CQuotationDetail001.Add(new CQuotationDetail001()
            {
                ID = (int)listItem["ID"],
                PersonID = Static_Common.ListItemToInt(listItem["PersonID"]),
                No = Static_Common.ListItemToInt(listItem["No"]),
                Desc01 = Static_Common.ListItemToString(listItem["Desc01"]),
                Quantity = Static_Common.ListItemToInt(listItem["Quantity"]),
                unit = Static_Common.ListItemToString(listItem["unit"]),
                StandardPrice = Static_Common.ListItemToDecimal(listItem["StandardPrice"]),
                SalesPrice = Static_Common.ListItemToDecimal(listItem["SalesPrice"]),
                Amount = Static_Common.ListItemToDecimal(listItem["Amount"]),
                Memo = Static_Common.ListItemToString(listItem["Memo"]),
            });

        }

        ////////////////////////////////////////////////////////////////////////////
        ///  更新処理
        ////////////////////////////////////////////////////////////////////////////

        //明細行を削除・追加するために現在の明細行を取得する。
        static private SP.ListItemCollection _listItemsDetail = null;

        static public void AsyncUpload(Adapter_EventHandler<int> adapter_EventHandler, int nID, CQuotation cQuotation, ObservableCollection<CQuotationDetail001> oc_CQuotationDetail001)
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                SP.ListItem _listItem = null;
                //新規or更新
                {
                    var list = clientContext.Web.Lists.GetByTitle("List_Quotation");
                    //clientContext.Load(list);

                    if (0 == nID)
                    {
                        _listItem = list.AddItem(new SP.ListItemCreationInformation());
                    }
                    else
                    {
                        _listItem = list.GetItemById(nID);
                    }

                    _listItem["Approved"] = cQuotation.Approved;

                    _listItem["InvoiceID"] = cQuotation.InvoiceID;
                    _listItem["CustomerName"] = cQuotation.CustomerName;

                    _listItem["CreateDate"] = cQuotation.CreateDate;

                    _listItem["Subject1"] = cQuotation.Subject1;
                    _listItem["Subject2"] = cQuotation.Subject2;
                    _listItem["Other1"] = cQuotation.Other1;
                    _listItem["Other2"] = cQuotation.Other2;

                    _listItem["SubTotal"] = 0;
                    _listItem["ConsumptionTax"] = 0;
                    _listItem["TotalAmount"] = 0;

                    //_listItem["RowData"] = cQuotation.RowData;
                    _listItem["Memo"] = cQuotation.Memo;

                    _listItem.Update();

                    //Load GetItemByIdで取得したときには必要
                    clientContext.Load(_listItem);
                }

                //明細行取得
                {
                    var list = clientContext.Web.Lists.GetByTitle("List_QuotationDetail001");
                    clientContext.Load(list);
                    var strWhere = "<Where><Eq><FieldRef Name='PersonID' /><Value Type='Integer'>" + nID.ToString() + "</Value></Eq></Where>";
                    _listItemsDetail = GetItemsFromCAMLQuery(list, strWhere);
                    clientContext.Load(_listItemsDetail);

                }

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        int nNewID = 0;
                        try
                        {
                            nNewID = _listItem.Id;
                            //明細行を取得する。
                            AsyncUpload_Sub_Detail001(
                                new Adapter_EventHandler(delegate(bool IsSuccess, Exception e2)
                                {
                                    adapter_EventHandler(IsSuccess, e2, nNewID);
                                }),
                                nNewID,
                                oc_CQuotationDetail001);
                        }
                        catch (Exception ex2)
                        {
                            adapter_EventHandler(false, ex2, nNewID);
                        }
                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                        adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message), 0);
                    }));
            }
        }
        static private void AsyncUpload_Sub_Detail001(Adapter_EventHandler adapter_EventHandler, int nID, ObservableCollection<CQuotationDetail001> oc_CQuotationDetail001)
        {
            try
            {
                using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
                {
                    var list = clientContext.Web.Lists.GetByTitle("List_QuotationDetail001");
                    //clientContext.Load(list);

                    //明細行削除
                    {
                        foreach (var li in _listItemsDetail)
                        {
                            SP.ListItem item = list.GetItemById(li.Id);
                            item.DeleteObject();
                        }
                    }

                    //明細行追加
                    {
                        SP.ListItem item = null;
                        for (int i = 0; i < oc_CQuotationDetail001.Count; i++)
                        {
                            item = list.AddItem(new SP.ListItemCreationInformation());
                            item["PersonID"] = nID;
                            item["No"] = oc_CQuotationDetail001[i].No;
                            item["Desc01"] = oc_CQuotationDetail001[i].Desc01;
                            item["Quantity"] = oc_CQuotationDetail001[i].Quantity;
                            item["unit"] = oc_CQuotationDetail001[i].unit;
                            item["StandardPrice"] = oc_CQuotationDetail001[i].StandardPrice;
                            item["SalesPrice"] = oc_CQuotationDetail001[i].SalesPrice;
                            item["Amount"] = oc_CQuotationDetail001[i].Amount;
                            item["Memo"] = oc_CQuotationDetail001[i].Memo;
                            item.Update();
                        }
                    }

                    clientContext.ExecuteQueryAsync(
                            new SP.ClientRequestSucceededEventHandler(delegate(object o3, SP.ClientRequestSucceededEventArgs successargs3)
                            {
                                adapter_EventHandler(true, null);
                            }),
                            new SP.ClientRequestFailedEventHandler(delegate(object o3, SP.ClientRequestFailedEventArgs failedArgs)
                            {
                                adapter_EventHandler(false, new Exception(failedArgs.ErrorDetails + "   " + failedArgs.Message));
                            }));

                }
            }
            catch (Exception ex2)
            {
                adapter_EventHandler(false, ex2);
            }

        }

    }

    // 表示するためのデータのクラス

    public class CQuotation : CData
    {
        public bool Approved { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string InvoiceID { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string CustomerName { get; set; }
        public DateTime CreateDate { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Subject1 { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Subject2 { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Other1 { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Other2 { get; set; }
        public decimal Subtotal { get; set; }
        public decimal ConsumptionTax { get; set; }
        public decimal TotalAmount { get; set; }
        //public string RowData { get; set; } 
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Memo { get; set; } 
    }

    // 表示するためのデータのクラス
    public class CQuotationDetail001 : CData
    {
        public int PersonID { get; set; }
        public int No { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Desc01 { get; set; }
        public decimal Quantity { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string unit { get; set; }
        public decimal StandardPrice { get; set; }
        public decimal SalesPrice { get; set; }
        public decimal Amount { get; set; }
        [XmlElement(IsNullable = true)]//Nullデータの場合でもタグが省略されないようにする。
        public string Memo { get; set; }
    }
}

Adapter_Base0100.cs (Baseクラス)

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using SP = Microsoft.SharePoint.Client;
using System.Collections.ObjectModel;

namespace SilverlightProjectMain.Models.SharepointClient.Base
{
    //デリゲート
    public delegate void Adapter_EventHandler(bool IsSuccess, Exception e);
    public delegate void Adapter_EventHandler<Type>(bool IsSuccess, Exception e, Type typeData);
    public delegate void Adapter_EventHandlerCollection<Type>(bool IsSuccess, Exception e, System.Collections.ObjectModel.ObservableCollection<Type> observableCollection);
    public delegate void Adapter_EventHandlerCollection<Type1, Type2>(bool IsSuccess, Exception e, System.Collections.ObjectModel.ObservableCollection<Type1> observableCollection1, System.Collections.ObjectModel.ObservableCollection<Type2> observableCollection2);

    public class CData
    {
        public int ID { get; set; }
    }

    public class Adapter_Base0100
    {
        protected enum SearchType
        {
            ID,
            All,
            Type001,
            Type002,
            Type003,
            Type004,
            Type005
        }
        protected const int DEFAULT_ROWLIMIT = 30;

        //Sample 動作OKのCAML
        //var camlQuery = new SP.CamlQuery();
        //camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='ID' /><Value Type='Integer'>1</Value></Eq></Where></Query></View>";
        //camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='CustomerName' /><Value Type='Text'>111</Value></Eq></Where></Query></View>";
        //camlQuery.ViewXml = "<View><Query><Where><Contains><FieldRef Name='CustomerName' /><Value Type='Text'>111</Value></Contains></Where></Query></View>";

        //その他キーワード(StartWith, In)

        //listItems = list.GetItems(camlQuery);
        //clientContext.Load(listItems);

        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list)
        {
            return GetItemsFromCAMLQuery(list, "", "");
        }
        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list, string strWhere)
        {
            return GetItemsFromCAMLQuery(list, strWhere, "");
        }
        static protected SP.ListItemCollection GetItemsFromCAMLQuery(SP.List list, string strWhere, string strOrderBy)
        {
            var camlQuery = new SP.CamlQuery();

            string strTemp = "<View>";
            strTemp += "<Query>" + strWhere + "</Query> ";
            strTemp += "<RowLimit>" + DEFAULT_ROWLIMIT.ToString() + "</RowLimit>";
            strTemp += strOrderBy;
            strTemp += "</View>";

            camlQuery.ViewXml  = strTemp;
            return list.GetItems(camlQuery);
        }

    }

}

StaticCommon.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;
using System.Collections.ObjectModel;

namespace SilverlightProjectMain
{
    public static class Static_Common
    {

        //シリアル化
        public static string XmlSerializeToString(this object objectInstance)
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(objectInstance.GetType());
            var sb = new System.Text.StringBuilder();

            using (System.IO.TextWriter writer = new System.IO.StringWriter(sb))
            {
                serializer.Serialize(writer, objectInstance);
            }

            return sb.ToString();
        }

        public static T XmlDeserializeFromString<T>(string objectData)
        {
            return (T)XmlDeserializeFromString(objectData, typeof(T));
        }

        private static object XmlDeserializeFromString(string objectData, Type type)
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(type);
            object result;

            using (System.IO.TextReader reader = new System.IO.StringReader(objectData))
            {
                result = serializer.Deserialize(reader);
            }

            return result;
        }

        static public int ListItemToInt(object objectData)
        {
            if (null == objectData)
            {
                return 0;
            }
            else
            {
                return int.Parse(objectData.ToString());
            }
        }

        static public string ListItemToString(object objectData)
        {
            if (null == objectData)
            {
                return "";
            }
            else
            {
                return objectData.ToString();
            }
        }
        static public decimal ListItemToDecimal(object objectData)
        {
            if (null == objectData)
            {
                return 0;
            }
            else
            {
                return Decimal.Parse(objectData.ToString());
            }
        }
        static public DateTime ListItemToDateTime(object objectData)
        {
            if (null == objectData)
            {
                throw new Exception("Error; ListItemToDateTime; Data is Null");
            }
            else
            {
                return (DateTime)objectData;
            }
        }

        static public void ThrowExceptionBeginInvoke(Control control, bool IsSuccess, Exception e)
        {
            if (!IsSuccess)
            {
                //WIndows のイベントでないときに(例:コールバック)throwすると app.xaml.csでエラーウインドウがよびだせなくなる。
                control.Dispatcher.BeginInvoke(new Action(delegate() { throw e; }), null);
            }

        }
        static public void ThrowExceptionBeginInvoke(Control control, Exception ex)
        {
            //WIndows のイベントでないときに(例:コールバック)throwすると app.xaml.csでエラーウインドウがよびだせなくなる。
            control.Dispatcher.BeginInvoke(new Action(delegate() { throw ex; }), null);
        }

        static public Boolean ShowYesCancel(Control control, string strMesage)
        {
            MessageBoxResult result = MessageBox.Show(strMesage, Define.APPLICTION_TITLENAME, MessageBoxButton.OKCancel);

            if (MessageBoxResult.OK == result)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        static public void ShowNormal(Control control, string strMesage)
        {
            control.Dispatcher.BeginInvoke(new Action(delegate() { MessageBox.Show(strMesage, Define.APPLICTION_TITLENAME, MessageBoxButton.OK); }), null);
        }

        static public void EnableControlBeginInvoke(Control control, bool IsEnabled)
        {
            control.Dispatcher.BeginInvoke(new Action(delegate() { control.IsEnabled = IsEnabled; }), null);
        }
    }
}

新規登録時にIDを取得する方法(Client Object Model, Sharepoint Online(Office365), Silverlight, C#)

新規登録時にIDを取得する方法

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using SP = Microsoft.SharePoint.Client;

using SilverlightProjectMain.Models.SharepointClient.Base;

namespace SilverlightProjectMain.Models.SharepointClient
{
    public class Adapter_CQuotation : Adapter_Base0100
    {
        //新規追加時にID取りたいのでこのスコープで宣言
        static private SP.ListItem _listItem = null;
        static public void Test()
        {
            using (var clientContext = new SP.ClientContext(SP.ApplicationContext.Current.Url))
            {
                var list = clientContext.Web.Lists.GetByTitle("List_Quotation");
                //clientContext.Load(list);

                _listItem = list.AddItem(new SP.ListItemCreationInformation());

                _listItem["InvoiceID"] = "AAAAAA";
                _listItem["CustomerName"] = "BBBBBB";

                _listItem.Update();

                //Load 不要
                //clientContext.Load(list, olist => olist.Title);

                clientContext.ExecuteQueryAsync(
                    new SP.ClientRequestSucceededEventHandler(delegate(object o, SP.ClientRequestSucceededEventArgs successargs)
                    {
                        int nID = _listItem.Id;
                    }),
                    new SP.ClientRequestFailedEventHandler(delegate(object o, SP.ClientRequestFailedEventArgs failedArgs)
                    {
                    })                );
            }
        }
    }
}