Create SharePoint 2010 ribbon button programmatically w/o feature XML - sharepoint-2010

I have to create a SharePoint 2010 ribbon element (tabs, buttons, groups, etc.). Is there a way to create such elements via the SharePoint API without using custom actions?
Edit:
I've just found the possibilty to add elements like this (link):
SPRibbon r = SPRibbon.GetCurrent(Page);
r.RegisterDataExtension(/* XmlNode containing ribbon element code */);
Another workaround would be to append a custom web control and append dynamic controls to this "placeholder".
Is there a way to create elements without using xml nodes?

For layouts pages and webparts, you can create Ribbon without any XML, using Ribbon Utils for SharePoint 2010.
For example, for layouts page, you will need to inherit from RibbonUtils.RibbonLayoutsPage and provide your definition of a ribbon.
Code for the most simple page with custom ribbon tab & one button on it will look like this:
public partial class MyRibbonPage : RibbonLayoutsPage
{
public override TabDefinition GetTabDefinition()
{
return new TabDefinition()
{
Id = "TestRibbon",
Title = "Test",
Groups = new GroupDefinition[]
{
new GroupDefinition()
{
Id = "TestGroup",
Title = "Test group",
Template = GroupTemplateLibrary.SimpleTemplate,
Controls = new ControlDefinition[]
{
new ButtonDefinition()
{
Id = "TestButton",
Title = "Test button",
CommandJavaScript = "alert('test!');",
Image32Url = "/_layouts/images/lg_ICHLP.gif",
}
}
}
}
};
}
}
You will find more examples and very good documentation on the project page on CodePlex.
AFAIK, it is for now most simple and quick way to create ribbon programmatically for application pages & webparts.

Related

how to open multiple windows from the controller in asp.net MVC

How to open multiple windows from the controller?
For example, I have a controller that gets all the clients and for each client I want that his info is displayed in a different window or tab.
Is that possible using asp.net MVC 4?
I've done this exact thing, it was based on a button click which would fire multiple windows based on the parameters. Here's what you could do. Your controller would be like this...
[HttpPost]
public ActionResult CopyOpportunitySave(CopyOpportunityViewModel model)
{
ViewModel model = new ViewModel();
foreach (var url in "List object that contains URLS")
{
model.ClientURLs.Add(url);
}
return View("CopyOpportunity", model);
}
So now your Model class will have a property like
public List<string> ClientURLs{get; set;}
which is populated by all the URLs you will need to do a window.Open.
and Now in your view you can say
#foreach (var u in ViewModel.ClientURLs)
{
<script>
window.open(u);
</script>
}
just as long as the script inside the foreach loop is getting executed, it will work
This won't be possible by just using native MVC 4. However, one could think of some work-arounds which might resemble your requirements. For starters, is it necessary to actually open a 'browser tab' per client, or could this also be a tab page per client in one single HTML-document. If the latter is an option, you could take a look at different 'tab' controls being available in HTML.
If your really want a new browser window per client, my hint would be to return the list of possible clients to one HTML page and then use scripting in that HTML page to open a popup window for each client. For each popup / client an additional request needs to be send to the server.
Just make the link (<a></a>) that opens the client information have a target = "_blank":
John Smith
If you are using Html helpers it could be like this:
#Html.ActionLink("John Smith", "Details", "Clients", new {id = 1}, new { target = "_blank"})
This will open a new browser tab with the page you need.

Qcube/Qcodo dynamic input fields

Does anybody have an example how can I add dynamically input fields in my qcubed project?
Thanks!
You can utilize the QPanel control to add controls on the fly. Just set its AutoRenderChildren attribute to true and set the dynamic controls parent to the QPanel.
// Instantiate our QPanel - this will render a div to contain our dynamic controls
// Note that the parent is $this. You will need to call render in your template
$this->pnl = new QPanel($this);
// Setting AutoRenderChildren so that the Panel will handle Rendering our dynamic
// controls.
$this->pnl->AutoRenderChildren = true;
// Creating a button with an Ajax action to create our dynamic controls
$this->btn = new QButton($this);
$this->btn->Text = "Add Control";
$this->btn->AddAction(new QClickEvent(), new QAjaxAction('btn_Click'));
protected function btn_Click($strFormId, $strControlId, $strParameter) {
// create the control and set its parent to the QPanel
$ctl = new QTextBox($this->pnl);
}
You can get more information on using QPanels on the QCubed examples website.
QCubed QPanel Example

How might I create a SharePoint 2010 content query web part programatically?

How might I create a SharePoint 2010 content query web part programatically and add it to a SharePoint page?
The post Adding/Removing web part in SharePoint website programmatically using C# code contains a detailed description of adding and removing Web Parts.
Here's a snippet taken from the above post adding a Web Part to a page (replace the WebPartToBeAdded pseudoclass with ContentByQueryWebPart):
using (SPSite spSiteTest = new SPSite(“SiteURL”)
{
using (SPWeb spWebTest = spSiteTest.OpenWeb())
{
SPWebPartCollection webparts = spWebTest.GetWebPartCollection("WebPageURL",Storage.Shared);
//create new webpart object
WebPartToBeAdded wpNew = new WebPartToBeAdded();
//set properties of new webpart object
wpNew.ZoneID = "WebPartZoneIDWhereWebPartIsToBeAdded";
wpNew.Title = "Web Part Title";
wpNew.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
wpNew.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.None;
//add new webpart object to webparts collection
webparts.Add(wpNew);
//update spWeb object
spWebTest.Update();
}
}

Outlook "save as html" on a mail message toolbar

The medical company I work for has a EMR system setup to keep digital copies of patient files so they are searchable as well as quick to access. A new request has come through to be able to save e-mail to the EMR system, however it does not display .msg files very nicely. It does display files nicely as .htm, so was hoping i could figure out a way to save email messages to a specific folder in a .htm format with the user just hitting a single button.
Should i be looking at making an add-in using vs 2010 to do this simple task? Or would there be a better way to do this?
I've explored making an Add-In breifly over the past few days using command bars but have hit numerous problems with adding the menu item to mail items, as well as losing event handlers or having them fire quite a few times, so i'm wondering if i'm barking up the wrong tree.
Edit: Looking at ribbon bar customization as well, may have to upgrade some users that are still using 2003, but seems like it might be the better option than command bars going forward.
Ribbon bar was the best path i found, however i had trouble finding a great how-to for the start-to-finish project, so i'll make a small write up here.
To add a button to the ribbon for only existing mail messages including a image for the button.
Using VS 2010
New project, Office, select "Outlook 2007 add in", enter a name for your project.
To your newly created project, Add a new item "Ribbon (XML)" name it however you want, i'll call it CustomRibbon
open your newly created CustomRibbon.xml file and change the tab node to have the following
<tab idMso="TabReadMessage">
<group insertBeforeMso="GroupActions" id="CustomGroup" label="GroupNameThatShowsInOutlook">
<button id="btnCustomButton"
label = "Text For The Custom Button"
supertip="tip for the button hover"
onAction ="ButtonClicked"
size="large"
getImage="GetCustomButtonImage" />
</group>
</tab>
This then has 2 callback functions to the CustomRibbon.cs file, one called GetCustomButtonImage, the other ButtonClicked.
open CustomRibbon.cs to fill this in, in the Ribbon Callbacks region add the following
public void ButtonClicked(Office.IRibbonControl Control)
{
//Do work here
}
also add the following in the same section
public stdole.IPictureDisp GetCustomButtonImage(Office.IRibbonControl control)
{
System.Drawing.Image myImage;
myImage = OutlookAddIn.Properties.Resources.ImageName;
return AxHostConverter.ImageToPictureDisp(myImage);
}
this will then show there is a class missing, we'll get to that shortly, but first we are going to add in the last part we need in CustomRibbon.cs. In the IRibbonExtensibility Members region, in GetCustomUI change the existing code
public string GetCustomUI(string ribbonID)
{
if (ribbonID == "Microsoft.Outlook.Mail.Read")
{
return GetResourceText("OutlookAddIn.CustomRibbon.xml");
}
else
{
return "";
}
}
Add a new class to your project call it AxHostConverter, add add this to the top
using System.Windows.Forms;
using System.Drawing;
Then change the class to have the following code
class AxHostConverter : AxHost
{
private AxHostConverter() : base("") { }
static public stdole.IPictureDisp ImageToPictureDisp(Image image)
{
return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
}
static public Image PictureDispToImage(stdole.IPictureDisp pictureDisp)
{
return GetPictureFromIPicture(pictureDisp);
}
}
Add your image for your button to the project, and change the GetCustomButtonImage function to use that resource. I used a PNG and had good luck with transparencies displaying well.
And finally, all that should be left is to add the following to ThisAddIn.cs
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new CustomRibbon();
}
Add whatever code you are wanting to ButtonClicked and you are set.
Deploy using Clickonce and installation is fairly straightforward.

Getting current Tab/Document in DockPanel Suite

I'm using the DockPanel Suite by Weifen Luo in a little project (webbrowser) and have managed to be able to create tabs and navigate the webbrowser element inside each tab.
But how am I able to change the tabs title/name when the page is navigating to another site?
Basically I just need to get into the current tabs form.
You can get the current tab by using DockPanel's ActiveContent method. For example:
Form myForm = myDockPanel.ActiveContent();
myForm.TabText = "Stack Overflow";
DockPanel.ActiveDocument and DockPanel.ActivePane can also be useful.
After having worked on this a few weeks (not 'till now though :P) I have to say, that this is currently not possible.
You can manage your own (assuming your Document Form is a specific class) by managing:
'FormClosing' and 'Activated' events
'Activated' set your own "active" document to 'this'.
'FormClosing' set your own "active" document to null.
FormClosing is just to catch the case where you are closing the last document. Activated is what manages everything else, like when a new document gets created and is made the active window, etc.
You can use a static global to manage focus. Then access it from anywhere else:
public partial class MyDocument : DockContent
{
public static MyDocument ActiveDocument { get; private set; }
I needed the ability to check which document was active, and set that document to active again after changing some UI elements that automatically reset the active tab, so I used some pieces from here and the DockPanel FAQ, and did some digging to figure out the answer to this problem:
public string GetActive()
{ //Verify if forms that dock in main window are already open
foreach (DockContent form in dockMain.Contents)
{
if (form.DockHandler.Pane.ActiveContent.DockHandler.Form.Name.ToString() == form.Name.ToString())
{
string formName = form.Name.ToString();
return formName;
}
}
return null;
}
And then in some other method you will call:
string activeForm = GetActive();