none
Modifying the toolbar type of an XsltListViewWebpart programatically RRS feed

  • Question

  • Hello everyone,

    I want to add a number of XsltListViewWebpart to a page, and modify the Toolbar Type of the webparts programatically.

    I can successfully add the webpart to the page using the following:

    private static void AddListViewWebPart(string siteCollUrl, string siteRelativeUrl, String pageUrl, string listName, string webPartTitle, String zoneId, int zoneIndex, string viewName, PartChromeType chromeType)
    {
     using (SPSite site = new SPSite(siteCollUrl))
     {
      using (SPWeb web = site.AllWebs[siteRelativeUrl])
      {
       SPLimitedWebPartManager lwpm = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared);
       SPList list = web.Lists[listName];
              
       XsltListViewWebPart lvwp = new XsltListViewWebPart();
       lvwp.ListId = list.ID;
       lvwp.ViewGuid = list.Views[viewName].ID.ToString("B").ToUpper(CultureInfo.InvariantCulture);
       lvwp.AllowClose = false;
       lvwp.AllowConnect = false;
       lvwp.AllowEdit = false;
       lvwp.AllowHide = false;
       lvwp.AllowMinimize = false;
       lvwp.AllowZoneChange = false;
       lvwp.Description = list.Description;
       lvwp.Title = webPartTitle;
       lvwp.ChromeType = chromeType;
    
       lwpm.AddWebPart(lvwp, zoneId, zoneIndex);
      }
     }
    }
    
    

    But I am having a problem modifying the toolbar type of the webpart.  I have found a few examples during my investigations:

    http://www.nearinfinity.com/blogs/joe_ferner/changing_the_toolbar_on_a_shar.html
    This looked promising but I am unable to cast an XsltListViewWebpart to a ListViewWebpart

    http://www.codekeep.net/snippets/9a2195d2-5d66-4af7-84f6-0a3bf147a1f5.aspx
    This also looked promising, but XSLTListViewwWebpart does not seem to have the property "View" any more - so I am assuming this was relevant for MOSS 2007.

    If anyone has any pointers, it would be greatly appreciated.

    Thanks,

    Kyle.

     

     

    Thursday, June 24, 2010 9:06 PM

Answers

  • Hi Kyle,

    Unfortunately, there isn't a public method for changing the toolbar type. However, it is possible to use reflection to access internal methods to do it. This is unsupported, and Internal methods/properties might change from version to version so this isn't guaranteed to always work, but here is some sample code you could add to the end of your function that will modify the toolbar type for an XsltListViewWebpart:

          try
          {
            MethodInfo ensureViewMethod = lvwp.GetType().GetMethod("EnsureView", BindingFlags.Instance | BindingFlags.NonPublic);
            object[] ensureViewParams = { };
            ensureViewMethod.Invoke(lvwp, ensureViewParams);
            FieldInfo viewFieldInfo = lvwp.GetType().GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
            SPView view = viewFieldInfo.GetValue(lvwp) as SPView;
            Type[] toolbarMethodParamTypes = { Type.GetType("System.String") };
            MethodInfo setToolbarTypeMethod = view.GetType().GetMethod("SetToolbarType", BindingFlags.Instance | BindingFlags.NonPublic, null, toolbarMethodParamTypes, null);
            object[] setToolbarParam = { "None" }; //set the type here
            setToolbarTypeMethod.Invoke(view, setToolbarParam);
            view.Update();
          }
          catch { }
    

    Thanks,

    Daniel McAllister--MSFT

    • Marked as answer by Kyle Winters Friday, June 25, 2010 1:04 AM
    Thursday, June 24, 2010 11:58 PM

All replies

  • Hi Kyle,

    Unfortunately, there isn't a public method for changing the toolbar type. However, it is possible to use reflection to access internal methods to do it. This is unsupported, and Internal methods/properties might change from version to version so this isn't guaranteed to always work, but here is some sample code you could add to the end of your function that will modify the toolbar type for an XsltListViewWebpart:

          try
          {
            MethodInfo ensureViewMethod = lvwp.GetType().GetMethod("EnsureView", BindingFlags.Instance | BindingFlags.NonPublic);
            object[] ensureViewParams = { };
            ensureViewMethod.Invoke(lvwp, ensureViewParams);
            FieldInfo viewFieldInfo = lvwp.GetType().GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
            SPView view = viewFieldInfo.GetValue(lvwp) as SPView;
            Type[] toolbarMethodParamTypes = { Type.GetType("System.String") };
            MethodInfo setToolbarTypeMethod = view.GetType().GetMethod("SetToolbarType", BindingFlags.Instance | BindingFlags.NonPublic, null, toolbarMethodParamTypes, null);
            object[] setToolbarParam = { "None" }; //set the type here
            setToolbarTypeMethod.Invoke(view, setToolbarParam);
            view.Update();
          }
          catch { }
    

    Thanks,

    Daniel McAllister--MSFT

    • Marked as answer by Kyle Winters Friday, June 25, 2010 1:04 AM
    Thursday, June 24, 2010 11:58 PM
  • Hi Daniel,

    Thanks very much for your response.  That worked a treat.

    I'm pasting my completed code here for anyone else that may wish to use it.

    Regards,

    Kyle.

    private static void AddListViewWebPart(string siteCollUrl, string siteRelativeUrl, String pageUrl, string listName, string webPartTitle, String zoneId, int zoneIndex, string viewName, PartChromeType chromeType, string toolbarType)
    {
     using (SPSite site = new SPSite(siteCollUrl))
     {
      using (SPWeb web = site.AllWebs[siteRelativeUrl])
      {
       SPLimitedWebPartManager lwpm = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared);
       SPList list = web.Lists[listName];
              
       XsltListViewWebPart lvwp = new XsltListViewWebPart();
       lvwp.ListId = list.ID;
       lvwp.ViewGuid = list.Views[viewName].ID.ToString("B").ToUpper(CultureInfo.InvariantCulture);
       lvwp.AllowClose = false;
       lvwp.AllowConnect = false;
       lvwp.AllowEdit = false;
       lvwp.AllowHide = false;
       lvwp.AllowMinimize = false;
       lvwp.AllowZoneChange = false;
       lvwp.Description = list.Description;
       lvwp.Title = webPartTitle;
       lvwp.ChromeType = chromeType;
    
       lwpm.AddWebPart(lvwp, zoneId, zoneIndex);
      }
     }
    
     SetWebpartToolbar(siteCollUrl, siteRelativeUrl, pageUrl, webPartTitle, toolbarType);
    }
    
    
    private static void SetWebpartToolbar(string siteCollUrl, string siteRelativeUrl, string pageRelativeUrl, string webPartTitle, string toolbarType)
    {
     using (SPSite site = new SPSite(siteCollUrl))
     {
      using (SPWeb web = site.AllWebs[siteRelativeUrl])
      {
       string pageUrl = siteCollUrl + siteRelativeUrl + pageRelativeUrl;
       SPLimitedWebPartManager lwpm = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared);
    
       for (int i = 0; i < lwpm.WebParts.Count; i++)
       {
        try
        {
         if (lwpm.WebParts[i].Title == webPartTitle)
         {
          XsltListViewWebPart lvwp = (XsltListViewWebPart)lwpm.WebParts[i];
    
          MethodInfo ensureViewMethod = lvwp.GetType().GetMethod("EnsureView", BindingFlags.Instance | BindingFlags.NonPublic);
          object[] ensureViewParams = { };
          ensureViewMethod.Invoke(lvwp, ensureViewParams);
          FieldInfo viewFieldInfo = lvwp.GetType().GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
          SPView view = viewFieldInfo.GetValue(lvwp) as SPView;
          Type[] toolbarMethodParamTypes = { Type.GetType("System.String") };
          MethodInfo setToolbarTypeMethod = view.GetType().GetMethod("SetToolbarType", BindingFlags.Instance | BindingFlags.NonPublic, null, toolbarMethodParamTypes, null);
          object[] setToolbarParam = { toolbarType };
          setToolbarTypeMethod.Invoke(view, setToolbarParam);
          view.Update();
         }
        }
        catch
        {
        }
       }
      }
     }
    }
    
    Friday, June 25, 2010 1:04 AM
  • The is another way to change the type of the toolbar without using reflection:

    public static void SetToolbarType(this SPView view, string type)
            {
                if (view == null)
                    throw new NullReferenceException("SPView.SetToolbarType(string) cannot be called on NULL-Values.");

                var xDoc = new System.Xml.XmlDocument();
                xDoc.LoadXml(view.GetViewXml());

                var toolbarNodeQuery = from System.Xml.XmlNode n in xDoc.DocumentElement.ChildNodes
                                       where n.Name == "Toolbar"
                                       select n;


                System.Xml.XmlElement toolbarNode = null;
                if (toolbarNodeQuery.Count() == 0)
                {
                    toolbarNode = xDoc.CreateElement("Toolbar");
                    xDoc.DocumentElement.AppendChild(toolbarNode);
                }
                else
                {
                    toolbarNode = xDoc.DocumentElement["Toolbar"];
                }
                toolbarNode.SetAttribute("Type", type);
                view.SetViewXml(xDoc.OuterXml);
                view.Update();
            }

    This method extends the SPView class by an instance method, which loads the view's xml data, updates the toolbar node and writes the data back to the SPView object.

    Greetings
    Robin Klass

    Wednesday, February 16, 2011 1:17 PM
  • Thanx Daniel It worked :)
    Friday, June 10, 2011 7:57 AM
  • Kyle: I can't figure out how you got this to work. This line fails

    <br/>      FieldInfo viewFieldInfo = lvwp.GetType().GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
    
    

    ... because there's no field called "view".

    Friday, February 24, 2012 6:23 PM
  • I would just like to note that I think it's bad design that you must resort to reflection in order to set a property that is available through the SharePoint Web User Interface for editing a Web Part.  Sorry, this one resulted in large amount of wasted time for me.

    Brian McCullough

    Monday, August 13, 2012 1:48 PM