Outlook Addin: Custom Ribbon not visible in the main application window although RibbonType includes to Microsoft.Outlook.Explorer - vsto

I created an Outlook 2016 Addin which shows perfectly in the Inspector Windows for Appointments using the Ribbon Designer.
According to the documentation, I added the RibbonType Microsoft.Outlook.Explorer.
I would have expected that it would also show up on the start screen of Outlook:
Also, I cannot find any suitable RibbonType to set additionally so that the Addin shows on the start screen. Which should I add?
Where can I find good additional documentation of how to customize Outlook's Ribbons?
Do I have to switch to XML Customization? Is there documentation for how to move from Designer to XML?
I also included the Designer Code:
namespace OutlookAddIn4
{
partial class MyAddIn : Microsoft.Office.Tools.Ribbon.RibbonBase
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
public MyAddIn()
: base(Globals.Factory.GetRibbonFactory())
{
InitializeComponent();
}
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">"true", wenn verwaltete Ressourcen gelöscht werden sollen, andernfalls "false".</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für Designerunterstützung -
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.tab1 = this.Factory.CreateRibbonTab();
this.group1 = this.Factory.CreateRibbonGroup();
this.btnAddMyAddIn = this.Factory.CreateRibbonButton();
this.btnViewInMyAddIn = this.Factory.CreateRibbonButton();
this.btnRemoveFromMyAddIn = this.Factory.CreateRibbonButton();
this.btnSettings = this.Factory.CreateRibbonButton();
this.tab1.SuspendLayout();
this.group1.SuspendLayout();
this.SuspendLayout();
//
// tab1
//
this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
this.tab1.ControlId.OfficeId = "TabAppointment";
this.tab1.Groups.Add(this.group1);
this.tab1.Label = "TabAppointment";
this.tab1.Name = "tab1";
//
// group1
//
this.group1.Items.Add(this.btnAddMyAddIn);
this.group1.Items.Add(this.btnViewInMyAddIn);
this.group1.Items.Add(this.btnRemoveFromMyAddIn);
this.group1.Items.Add(this.btnSettings);
this.group1.Label = "MyAddIn";
this.group1.Name = "group1";
this.group1.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupActions");
//
// btnAddMyAddIn
//
this.btnAddMyAddIn.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnAddMyAddIn.Image = global::OutlookAddIn4.Properties.Resources.do_48x48;
this.btnAddMyAddIn.Label = "Add Minutes";
this.btnAddMyAddIn.Name = "btnAddMyAddIn";
this.btnAddMyAddIn.ShowImage = true;
this.btnAddMyAddIn.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnAddMyAddIn_Click);
//
// btnViewInMyAddIn
//
this.btnViewInMyAddIn.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnViewInMyAddIn.Image = global::OutlookAddIn4.Properties.Resources.do_48x48;
this.btnViewInMyAddIn.Label = "View Minutes";
this.btnViewInMyAddIn.Name = "btnViewInMyAddIn";
this.btnViewInMyAddIn.ShowImage = true;
this.btnViewInMyAddIn.Visible = false;
this.btnViewInMyAddIn.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.ViewInMyAddIn_Click);
//
// btnRemoveFromMyAddIn
//
this.btnRemoveFromMyAddIn.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnRemoveFromMyAddIn.Image = global::OutlookAddIn4.Properties.Resources.do_48x48;
this.btnRemoveFromMyAddIn.Label = "Remove Minutes";
this.btnRemoveFromMyAddIn.Name = "btnRemoveFromMyAddIn";
this.btnRemoveFromMyAddIn.ShowImage = true;
this.btnRemoveFromMyAddIn.Visible = false;
this.btnRemoveFromMyAddIn.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.RemoveFromMyAddIn_Click);
//
// btnSettings
//
this.btnSettings.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnSettings.Image = global::OutlookAddIn4.Properties.Resources.do_48x48;
this.btnSettings.Label = "Settings";
this.btnSettings.Name = "btnSettings";
this.btnSettings.ShowImage = true;
this.btnSettings.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.Settings_Click);
//
// MyAddIn
//
this.Name = "MyAddIn";
this.RibbonType = "Microsoft.Outlook.Appointment, Microsoft.Outlook.Explorer";
this.StartFromScratch = true;
this.Tabs.Add(this.tab1);
this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.MyAddIn_Load);
this.tab1.ResumeLayout(false);
this.tab1.PerformLayout();
this.group1.ResumeLayout(false);
this.group1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
internal Microsoft.Office.Tools.Ribbon.RibbonGroup group1;
internal Microsoft.Office.Tools.Ribbon.RibbonButton btnAddMyAddIn;
internal Microsoft.Office.Tools.Ribbon.RibbonButton btnViewInMyAddIn;
internal Microsoft.Office.Tools.Ribbon.RibbonButton btnRemoveFromMyAddIn;
internal Microsoft.Office.Tools.Ribbon.RibbonButton btnSettings;
internal SettingsForm settingsForm;
}
partial class ThisRibbonCollection
{
internal MyAddIn MyAddIn
{
get { return this.GetRibbon<MyAddIn>(); }
}
}
}

I was kind of stupid.
The RibbonType is only a rough preselection of the areas where your addin is enabled to be visible. To precisely define the areas where to add your Ribbon you also need to define
your tab's OfficeId as follows:
this.tab1.ControlId.OfficeId = "TabAppointment";
From the example code above you see this is set to TabAppointment.
to find other valid tabs you may find the following list helpful
From this I conclude: If you want to show your Custom Ribbon in multiple windows (e.g. main window and calendar and appointment) you want to have multiple ribbons attached to various OfficeIds.

The Ribbon (Visual Designer) item does not support all possible types of Ribbon customization. To customize the ribbon in advanced ways, you can export the ribbon from the designer to Ribbon XML and edit the XML directly. The How to: Export a ribbon from the Ribbon Designer to Ribbon XML article describes the task in detail, so you may continue with XML and all features provided by the Fluent UI.
The Fluent UI (aka Ribbon UI) is described in-depth in the following series of articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Related

NetOffice - Custom Task Pane in a Appointment window in Outlook

I found out that it's possible to add custom task panes to individual windows like e.g. the appointment with this code snippet:
public void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
Microsoft.Office.Tools.CustomTaskPane myCustomTaskPane;
if(Inspector.CurrentItem is Microsoft.Office.Interop.Outlook.AppointmentItem ) {
UserControl uc1 = MyUserControl();
myCustomTaskPane = getAddIn().CustomTaskPanes.Add(uc1, "MyPanel",Inspector);
myCustomTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
myCustomTaskPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
myCustomTaskPane.Visible = true;
}
//Additionally You can add a property change listener to the current Item here
}
however, I use 'NetOffice' instead of VSTO to have the add-in compatible with various Outlook versions. And there the add-in doesn't have the CustomTaskPanes property, and the TaskPanes.Add property isn't overloaded to allow adding custom panes on other window than the main explorer.
Ok, worked it out in following way.
In the ComAddin class I have a local variable
Office._CustomTaskPane _taskPane;
and I set the variable on the overriden CTPFactoryAvailable method:
public override void CTPFactoryAvailable(object CTPFactoryInst)
{
_ctpFactory = new NetOffice.OfficeApi.ICTPFactory(this.Application, CTPFactoryInst);
}
Then - when the addin is loaded - I'm adding an event handler to the NewInspectorEvent event:
private void Addin_OnStartupComplete(ref Array custom)
{
var inspectors = Application.Inspectors as NetOffice.OutlookApi.Inspectors;
inspectors.NewInspectorEvent += Inspectors_NewInspectorEvent;
}
In the event handler for creating a new inspector window, I'm creating the pane:
private void Inspectors_NewInspectorEvent(_Inspector Inspector)
{
var ai = Inspector.CurrentItem as AppointmentItem;
if (ai == null)
return;
var ins = Inspector as NetOffice.OutlookApi.Inspector;
_taskPane = _ctpFactory.CreateCTP(typeof(Addin).Assembly.GetName().Name + ".UserControl1", "My title", Inspector);
_taskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionTop;
_taskPane.Height = 50;
_taskPane.Visible = true;
}
This draft proof of concept works for me.

Load all Appointment Properties, including extended properties, in Exchange 2010

I'm trying to list all the properties associated with a given calendar appointment, but I can't figure out if there's a way to do it without loading each property individually. Based on some of the code I've seen online, I know I can do something like the following:
/// <summary>
/// List all the properties of an appointment
/// </summary>
public void listProps()
{
Folder myCalendar = Folder.Bind(service, WellKnownFolderName.Calendar);
ItemView view = new ItemView(10);
FindItemsResults<Item> findResults;
do
{
findResults = myCalendar.FindItems(new SearchFilter.IsEqualTo(ItemSchema.ExtendedProperties, MyPropertySetId), view);
service.LoadPropertiesForItems(findResults, new PropertySet(ItemSchema.Subject, ItemSchema.Body));
foreach (Item item in findResults)
{
Console.WriteLine(item.Subject);
Console.WriteLine(item.Body);
}
if (findResults.NextPageOffset.HasValue)
{
view.Offset = findResults.NextPageOffset.Value;
}
} while (findResults.MoreAvailable);
}
However, what I'm really looking for there in the middle is something like this pseudo code:
service.LoadPropertiesForItems(findResults, new PropertySet(*.*));
foreach (Item item in findResults)
{
Console.WriteLine(property)
}
Is this possible?
Thanks!
No, it is not possible.
You can use predefined property sets like: PropertySet.FirstClassProperties to get the known set of properties.
Getting extended properties this way is not supported at all. You have to specify explicitly which extended properties you want to access. For example:
ItemView view = new ItemView(10);
ExtendedPropertyDefinition extendedPropertyDefinition =
new ExtendedPropertyDefinition("Expiration Date", MapiPropertyType.String);
view.PropertySet =
new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Subject,extendedPropertyDefinition);

when i update UIMap in coded UI test , the UIMap.Designer.cs file overwrite on my code

when i record a test method for "Login Scenario" with Coded UI test , it generates code like this
Generated Code
public void LoginMethod()
{
#region Variable Declarations
WinEdit uIItemEdit = this.UIDiagnosoftVIRTUEWindow.UIItemWindow.UIItemEdit;
WinEdit uIItemEdit1 = this.UIDiagnosoftVIRTUEWindow.UIItemWindow1.UIItemEdit;
WinComboBox uIItemComboBox = this.UIDiagnosoftVIRTUEWindow.UIItemWindow2.UIItemComboBox;
WinButton uIConnectButton = this.UIDiagnosoftVIRTUEWindow.UIConnectWindow.UIConnectButton;
#endregion
// Type 'username' in 'Unknown Name' text box
uIItemEdit.Text = this.LoginMethodParams.UIItemEditText;
// Type '********' in 'Unknown Name' text box
Keyboard.SendKeys(uIItemEdit1, this.LoginMethodParams.UIItemEditSendKeys1, true);
// Select 'facility' in 'Unknown Name' combo box
uIItemComboBox.SelectedItem = this.LoginMethodParams.UIItemComboBoxSelectedItem;
// Click 'Connect' button
Mouse.Click(uIConnectButton, new Point(64, 14));
}
i update this code to allow Data Driven Source ,CSV file which contains username,password,....
here is the updated code
Updated Code
public void LoginMethod(string username,string password,string facility)
{
#region Variable Declarations
WinEdit uIItemEdit = this.UIDiagnosoftVIRTUEWindow.UIItemWindow.UIItemEdit;
WinEdit uIItemEdit1 = this.UIDiagnosoftVIRTUEWindow.UIItemWindow1.UIItemEdit;
WinComboBox uIItemComboBox = this.UIDiagnosoftVIRTUEWindow.UIItemWindow2.UIItemComboBox;
WinButton uIConnectButton = this.UIDiagnosoftVIRTUEWindow.UIConnectWindow.UIConnectButton;
#endregion
// Type 'msameeh' in 'Unknown Name' text box
uIItemEdit.Text = username;
// Type '{Tab}' in 'Unknown Name' text box
uIItemEdit.Text=password;
// Select 'diagnosoft.com' in 'Unknown Name' combo box
uIItemComboBox.SelectedItem = facility;
// Click 'Connect' button
Mouse.Click(uIConnectButton, new Point(64, 14));
}
and i run test method and it works well But when i edit the UIMap to add unused controls like "Canncel button" or any other controls
like in this link
http://blogs.microsoft.co.il/blogs/shair/archive/2010/08/08/coded-ui-test-tip-4-add-unused-controls-to-ui-map.aspx
the UIMap.Designer.CS file overwrites my Login method Updated code with Genereated code
Thanks in Advance
You should not edit the *UIMap.Designer.cs files. Those are auto generated. That is the purpose of the *UIMap.cs file, for your custom methods and implementations that will not get overridden.
That is why the comment block at the top of the Designer files states not to edit them manually.

SharePoint 2010 event receiver,List Item Events, Document library,event ItemAdded not firing

in SharePoint Server 2010 i have a document library and i want to create sub-folders every time a folder created, i have a code snippet but it's not working, i tried to debug but also the event isn't firing, could any one help me please and here is my code:
public class EventReceiver1 : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
private string[] subFolders = new string[] { "sub-folder1", "sub-folder2", "sub folder3" };
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPWeb web = properties.OpenWeb();
SPDocumentLibrary ProductsLibrary = (SPDocumentLibrary)web.Lists[properties.ListId];
if (properties.ListItem.ContentType.Name.ToLower() == "new content type" && properties.ListItem.Folder.ParentFolder.ToString() == ProductsLibrary.RootFolder.ToString())
{
string Url = properties.ListItem.ParentList.RootFolder.ServerRelativeUrl.ToString();
SPFolder libFolder = ProductsLibrary.RootFolder.SubFolders[properties.ListItem.Name];
string newFolderUrl = (web.Url + "/" + libFolder.ToString());
foreach (string subfolder in subFolders)
{
SPListItem newSubFolder = ProductsLibrary.Items.Add(newFolderUrl, SPFileSystemObjectType.Folder, subfolder);
newSubFolder.Update();
}
}
}
}
thank you
the solution is to opent the elements.xml and replace the
with the and the code will run perfectly.
Make sure
you have added this event receiver as part of a feature
the feature containing this event receiver is activated
Event wont fire, if you have not followed the above steps

Sharepoint 2010 Event receiver not firing for subsite

I have an event receiver (WebAdding and WebProvisioned) which works just fine for sites created off the root of the site collection. However, subsites (for example, teamsites created within other areas) do not trigger the code at all.
Does anyone have any idea as to why?
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using System.Text;
namespace TestEventReceiver.EventReceiver1
{
/// <summary>
/// Web Events
/// </summary>
public class EventReceiver1 : SPWebEventReceiver
{
/// <summary>
/// A site is being provisioned.
/// </summary>
public override void WebAdding(SPWebEventProperties properties)
{
base.WebAdding(properties);
using (SPWeb web = properties.Web)
{
StringBuilder output = new StringBuilder();
output.AppendFormat("Web Adding");
output.AppendFormat("<br>Web title: {0}",web.Title);
SendMyEmail(web, "SendItToMe#MyTestAddress.com", "Web Adding", output.ToString());
}
}
/// <summary>
/// A site was provisioned.
/// </summary>
public override void WebProvisioned(SPWebEventProperties properties)
{
base.WebProvisioned(properties);
using (SPWeb web = properties.Web)
{
StringBuilder output = new StringBuilder();
output.AppendFormat("Web Provisioned");
output.AppendFormat("<br>Web title: {0}", web.Title);
SendMyEmail(web, "SendItToMe#MyTestAddress.com", "Web Provisioned", output.ToString());
}
}
private void SendMyEmail(SPWeb Web, String toAddress, String subject, String message)
{
bool appendHtmlTag = false;
bool htmlEncode = true;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPUtility.SendEmail(Web, appendHtmlTag, htmlEncode, toAddress, subject, message);
});
}
}
}
Thanks in advance,
Matt
I think you should not be using 'Using' .
The SPWeb object reference you get is from properties.Web which is being passed to the WebAdding method. You will run into issues because of this.
Have a look at how your event receiver is provisioned - it may be the scope needs to be changed to Site rather than Web. Perhaps you could post here so we can see.
On my site I had the same issue. Still figuring out the xml files, but in my Elements.xml file for the Receivers, each receiver had the same sequence number. Once I made them unique within the Elements.xml file, the WebProvisioned event started firing. Don't know if this is the same issue you were having.
This code is showing the WebAdding event and that event is occurring on the parent Web.
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spwebeventreceiver.webadding.aspx
Try to change scope of your receiver (in Elements.xml file add attribute ). Also, make sure that the feature of your Event receiver is activated in you site features in the subsite.