locked
プログラムからWebPartを移動(挿入)したい RRS feed

  • 全般的な情報交換

  • コード(C#)から
    WebPartの位置(ZoneとZoneIndex)を変更したいと思っています。

     

    SPLimitedWebPartManager.MoveWebPart()を使ってみたのですが、
    指定したZoneIndexにすでにWebPartが存在する場合
    勝手にそのZoneの最後尾に配置されてしまいます。

    このとき特にエラーは発生しません。

     

    # こういうものなのでしょうか?

    # それとも何か設定を間違っているでしょうか?

     

    希望の動作は指定のZoneIndex位置へ挿入するイメージです。

     

    そこで、そのZoneに存在するWebPartを
    いったん他のZoneへ移動して、
    あらためて対象のZoneへ入れなおすという方法で
    解決しようと思ったのですが、
    SharePointでWebPartZoneを取得する方法が分かりません。

     

    検索すると、WebPartを継承したクラスから

     

      this.WebPartManager.Zones

     

    としているコードを発見したのですが、
    WebPartManagerはプロテクトパラメータのようです。

     

    全てのWebPartについて
    WebPart.Zoneを調べればよいかなとも思いましたが、
    WebPart.Zoneは空(null)のようです。

     

    # こういうものなのでしょうか?

    # 私の環境がおかしい?

     

    どうすればWebPartを移動(挿入)できるのでしょうか?
    WebPartを継承したクラスを作成するしかないのでしょうか?


     

    以上です。

    よろしくお願いします。

     

     

    # 追記

     

    環境を書き忘れていました。

    下記環境で作業しています。

     

     WSS 3.0

     Windows Server 2003

    2008年6月26日 8:40

すべての返信

  • MSDNのMoveWebPartの説明を見ると、

    1. OnWebPartMoving メソッドは WebPartMoving イベントを発生させます。

    2. 現在のゾーンから webPart を削除し (必要な場合)、新しいゾーンまたは現在のゾーン内の新しい位置に追加します。

    3. OnWebPartMoved メソッドは WebPartMoved イベントを発生させます。

    4. 移動元のゾーンと移動先のゾーン両方についてすべての WebPart コントロールの zoneIndex をリセットして、移動したコントロールを反映します。

    とあるので挿入されない現状がおかしいようですね。

    うーん。。

     

    MoveWebPartのindex引数の説明をみると

     

    zone 内の他のコントロールに対する webPart の相対インデックスを示す整数。

     

    とありますね。

     

    「相対インデックス」ってなんでしょうか?

    2番目に移動したいからindex=1(0から始まるので)じゃダメなんでしょうか?
    2008年6月26日 8:57
  • 解決しました。

     

    権限が無くても移動できるように

    一律にRunWithElevatedPrivilegesして

    new SPSite(SPContext.Current.Web.Url, SPContext.Current.Site.SystemAccount.UserToken);

    としていたのがまずかったようです。

     

    お騒がせ致しました。

    m(_ _;)m
    2008年6月26日 9:14
  • 動いたと思ったのですが、

    やはりダメでした。

     

    正しく移動したり、しなかったりします。

    どうやらページに追加した順序が関係ある模様?

     

    最初に追加したWebPartはどこでも移動できて、

    2番目に追加したものは1番目より上でなければ

    どこでも移動できます。

     

    あと、移動後にWebPart.zoneIndexを調べてみると

    同じWebPartZone内の異なるWebPartが

    同じ値を持ってたりします。

     

    どういう仕様なのでしょう?

     

    とりあえず現状のコードを載せます。

    間違っているところがあれば

    指摘していただけると助かります。

     

     

    WebPartは

     ページを開いているユーザ自身が追加した、スコープUserのWebPart

     SystemAccount.UserTokenにて追加した、スコープShareのWebPart

    のどちらかのみが存在する形となります。

    これらの混在はありません。


     

    Code Snippet

    /// <summary>
    /// Webパーツの位置を移動する
    /// </summary>
    /// <param name="guid">対象WebパーツのGUID</param>
    /// <param name="zoneID">移動先ZoneのID</param>
    /// <param name="zoneIndex">移動先Zone内での位置</param>
    /// <returns>なし</returns>
    /// <remarks>
    /// 指定したWebパーツを指定したZoneの指定したIndex位置へ移動する
    /// </remarks>
    protected void MoveWebPart(string guid, string zoneID, string zoneIndex)
    {

        SPSite currentSite = null;
        SPWeb currentWeb = null;
        SPSite adminSite = null;
        SPWeb adminWeb = null;
        SPLimitedWebPartManager manager = null;
        WebPart targetWebPart = null;

        try
        {

            currentSite = SPContext.Current.Site;
            currentWeb = SPContext.Current.Web;
            currentWeb.AllowUnsafeUpdates = true;

            // 一旦スコープUserで取得する
            manager = currentWeb.GetLimitedWebPartManager(Request.CurrentExecutionFilePath, PersonalizationScope.User);
            targetWebPart = manager.WebParts[new System.Guid(guid)];

            // WebパーツのスコープがShareだったらmanagerを再設定
            if (targetWebPart.IsShared)
            {

                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    try
                    {
                        // Admin権限で取り直す
                        adminSite = new SPSite(SPContext.Current.Web.Url, SPContext.Current.Site.SystemAccount.UserToken);
                        adminWeb = adminSite.OpenWeb();
                        adminWeb.AllowUnsafeUpdates = true;

                        manager = adminWeb.GetLimitedWebPartManager(Request.CurrentExecutionFilePath, PersonalizationScope.Shared);
                        targetWebPart = manager.WebParts[new System.Guid(guid)];

                        int intZoneIndex = int.Parse(zoneIndex);
                        manager.MoveWebPart(targetWebPart, zoneID, intZoneIndex);
                        manager.SaveChanges(targetWebPart);
                    }
                    catch
                    {
                        throw;
                    }
                    finally
                    {
                        // SPSite,SPWebはDisposeが必須
                        if (adminWeb != null)
                        {
                            adminWeb.AllowUnsafeUpdates = false;
                            adminWeb.Dispose();
                        }
                        if (adminSite != null)
                        {
                            adminSite.Dispose();
                        }
                    }

                });
            }
            else {

                int intZoneIndex = int.Parse(zoneIndex);
                manager.MoveWebPart(targetWebPart, zoneID, intZoneIndex);
                manager.SaveChanges(targetWebPart);

            }
        }
        catch (Exception ex)
        {
            // エラー処理
        }
        finally
        {
            // SPSite,SPWebはDisposeが必須
            if (currentWeb != null)
            {
                currentWeb.AllowUnsafeUpdates = false;
                currentWeb.Dispose();
            }
            if (currentSite != null)
            {
                currentSite.Dispose();
            }
        }
    }

     

     

    2008年6月26日 18:40
  • ページに追加した順番は関係ない模様。

    最初に追加したWebPartでも正しく移動できない時がある。

    2008年6月26日 18:48
  • tak.05 さん、こんにちは。

    フォーラムオペレーターの鈴木裕子です

     

    その後いかがでしょうか?

    tak.05 さんのその後が気になるところではありますが、

    自力で解決に向かわれているようですので、よろしけば、メッセージの種類を「コメント」に変更いただけないでしょうか。

    (「質問」のままですと、せっかくの情報が埋もれてしまってもったいないのです・・・)

    お手数となりますが、よろしくお願いいたします。

    引き続き情報がありましたら、遠慮なくご投稿くださいね!

    それでは。

    2008年8月22日 5:03
    モデレータ