I downloaded an outlook add-in, which after install create the new tab on the ribbon, and create buttons on new tab. I would like to press these buttons without ui interaction.
I tried query installed add-ins, but can not be controlled:
static void Main( string[] args )
{
Microsoft.Office.Interop.Outlook.ApplicationClass app = new Microsoft.Office.Interop.Outlook.ApplicationClass();
for ( int c = 1; c < app.COMAddIns.Count; c++ )
{
Console.WriteLine( app.COMAddIns.Item( c ).Description );
if ( app.COMAddIns.Item( c ).Description.StartsWith( "XXX" ) )
{
string guid = app.COMAddIns.Item( c ).Guid; // Okay
object obj = app.COMAddIns.Item( c ).Object; // null
object parent = app.COMAddIns.Item( c ).Parent; // ApplicaionClass
string progId = app.COMAddIns.Item( c ).ProgId; // Okay
}
}
}
But it is possible, wrong way. Possible query the ribbon control's buttons?
You can't.
The actions of buttons in ribbons are not publicly available. You can't even programmatically call a click event on the button itself when you are inside the same add-in. (you can call the event handler, but that is just all .NET side without interfering with VSTO / Outlook.
No Office ribbon controls are exposed for the programmatic access.
You can use either UI Automation API or you can use Redemption (I am its author) and its SafeRibbon object (exposed by the SafeExplorer.Ribbon property) - it allows to enumerate and execute Outlook ribbon controls:
set sInspector = CreateObject("Redemption.SafeInspector")
sInspector.Item = Application.ActiveInspector
set Ribbon = sInspector.Ribbon
oldActiveTab = Ribbon.ActiveTab 'remember the currently selected tab
Ribbon.ActiveTab = "Task"
set Control = Ribbon.Controls("Assign Task")
Control.Execute
Ribbon.ActiveTab = oldActiveTab 'restore the active tab
Related
I have my main form and a dialogbox which is called from main. In my main form I have a label and a button that which properties I can't change. I'm using Visual Studio 2015, not sure if there is a bug regarding this. I also made sure my label and button are set to public to modify.
Code: (this is from the dialog box, this has a list box the function is triggered at selectindexchange)
else if ((short)lbDiscountTypes.SelectedValue == 2) //Senior
{
frm_Main main = new frm_Main();
main.VAT = false;
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
main.Dispose();
//INQUIRE DISCOUNT TYPES
var Discount = GC.CSHR_DiscountTypes.Where(Filter => Filter.DiscountCode == (short)lbDiscountTypes.SelectedValue);
decimal DP = 0.00m;
foreach (var item in Discount)
{
DP = item.DiscountPercentage;
}
foreach (var item in GC.CSHR_SORepo
.Where(Filter => Filter.Machine == MACHINE
&& Filter.SalesOrderNum == SALESORDERNUM
&& Filter.First_SRP == Filter.IMFSRP))
{
item.DiscountAmount = (item.SoldSRP * DP) / 100;
item.TotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATableSalesOnTotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATRate = 0.00m;
GC.SaveChanges();
}
Close();
}
The code below //INQUIRE DISCOUNT TYPES works well but not the one on top.
I've used debug mode to check if the lines are not being skipped over and they aren't.
You should pay attention to:
You are creating a new instance of your main form that you don't need (while it is open behind the dialog), so you need to get it not create a new instance
You are disposing the main form you created. main.Dispose();
In fact you are creating a new instance of main form and assigning values to those controls and then dispose it. While and instance of yor main form that you expect to see changes on it, is open and untouched behind your dialog.
To set value of those controls you can do one of these ways:
Option 1
Make your labelStatus and btnNonVat public. Open your main form in designer and select labelStatus and btnNonVat and in property grid, set Modifier to public. Then write this code:
//var main = Application.OpenForms.OfType<frm_Main>().FirstOrDefault();
var main = (frm_Main)Application.OpenForms["frm_Main"];
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
Option 2
Pass an instance of your frm_Main to your dialog and work with it.
Option 3
After closing the dialog, use values from dialog and set values of your main form
Looks like you are trying to create new form using frm_Main main = new frm_Main(); syntax. All you need to do is get the instance of your current form.
var _currentMainForm= Application.OpenForms[0];
or if you have given name to your form
var _currentMainForm = Application.OpenForms["MainFormName"];
Once you get the reference you can perform all your label updates.
The code on top creates a new form, changes the labels and then disposes the form.
I think you should change the labels of the existing form.
Like in the other answer said you are setting properties of controls into a new Form object and not in the form where you come from.
You should pass the form object into the parameters of the dialog, something like:
void myDialog(frm_Main callingForm)
{
callingForm.Textbox1.Text = "abc";
}
And call it from you main form like this
...
myDialog(this);
I want to add C# code (in my Outlook VSTO Addin) to create an appointment and show the Schedule Assistant view when it's displayed.
Below is the code I've written so far which creates an appointment, adds the recipient. But when the Display method is called, its displayed showing the default Appointment view. I want it to display the Schedule Assistant view and show the recipients I just added.
AppointmentItem newAppointment = Application.CreateItem(OlItemType.olAppointmentItem);
Recipients sentTo = newAppointment.Recipients;
Recipient sentInvite = null;
sentInvite = sentTo.Add(emailAddress);
sentInvite.Type = (int)OlMeetingRecipientType.olRequired;
sentTo.ResolveAll();
newAppointment.Display();
UPDATE
In my VSTO add-in project I've added a UserControl. And in this UserControl I have a Button control. And when the Button is clicked it runs the following code:
AppointmentItem newAppointment = Globals.ThisAddIn.Application.CreateItem(OlItemType.olAppointmentItem);
newAppointment.MeetingStatus = OlMeetingStatus.olMeeting;
Inspector inspector = newAppointment.GetInspector;
CommandBarControl commandBarControl = inspector.CommandBars.FindControl(Type.Missing, 14935);
commandBarControl.Execute();
Recipients recipients = newAppointment.Recipients;
Recipient readyByRecipient = null;
readyByRecipient = recipients.Add(emailAddress);
readyByRecipient.Type = (int)OlMeetingRecipientType.olRequired;
recipients.ResolveAll();
newAppointment.Display();
Marshal.ReleaseComObject(readyByRecipient);
Marshal.ReleaseComObject(recipients);
Marshal.ReleaseComObject(newAppointment);
Unfortunatey when I call the FindControl method (passing the ID value from the OutlookAppointmentItemControls.xlsx file) it returns null, so I can't call commandBarControl.Execute() to show the Schedule Assistant view.
And I've also tried calling the FindControl method after calling newAppointment.Display(), but it still returns null.
You need to set the MeetingStatus property of the AppointmentItem class to the olMeeting value before calling the Display method. For example:
Sub CreateAppt()
Dim myItem As Object
Dim myRequiredAttendee, myOptionalAttendee, myResourceAttendee As Outlook.Recipient
Set myItem = Application.CreateItem(olAppointmentItem)
myItem.MeetingStatus = olMeeting
myItem.Subject = "Strategy Meeting"
myItem.Location = "Conference Room B"
myItem.Start = #9/24/2015 1:30:00 PM#
myItem.Duration = 90
Set myRequiredAttendee = myItem.Recipients.Add("Nate Sun")
myRequiredAttendee.Type = olRequired
Set myOptionalAttendee = myItem.Recipients.Add("Kevin Kennedy")
myOptionalAttendee.Type = olOptional
Set myResourceAttendee = myItem.Recipients.Add("Conference Room B")
myResourceAttendee.Type = olResource
myItem.Display
End Sub
To see the Schedule Assistant view you can run the corresponding button on the ribbon programmatically. The Execute method of the CommandBars class can be used to run the Scheduling button. You just need to pass idMso of the built-in control. See Office 2013 Help Files: Office Fluent User Interface Control Identifiers for actual values.
Got it working. The solution is to call the ExecuteMso method with the Control Name value from the OutlookAppointmentItemControls.xlsx file. And it only seems to work if you call the ExecuteMso after the Display method has been called.
Below is the code to create a new Appointment (meeting) with a recipient, and show the Schedule Assistant view in the Inspector window.
AppointmentItem newAppointment = Globals.ThisAddIn.Application.CreateItem(OlItemType.olAppointmentItem);
newAppointment.MeetingStatus = OlMeetingStatus.olMeeting;
Recipients recipients = newAppointment.Recipients;
Recipient readyByRecipient = null;
readyByRecipient = recipients.Add(emailAddress);
readyByRecipient.Type = (int)OlMeetingRecipientType.olRequired;
recipients.ResolveAll();
newAppointment.Display();
Inspector inspector = newAppointment.GetInspector;
inspector.CommandBars.ExecuteMso("ShowSchedulingPage");
Marshal.ReleaseComObject(readyByRecipient);
Marshal.ReleaseComObject(recipients);
Marshal.ReleaseComObject(newAppointment);
Marshal.ReleaseComObject(inspector);
I'm trying to create a DevEx drop down button. Unfortunately, I'm running into two problems I can't figure out:
1) I can't get the popup menu to skin correctly, i.e. it doesn't skin as "Office 2010 Blue". The code I'm using is shown below:
private void InitializeSendToPricingSheetButton()
{
var barManager = new BarManager();
if (barManager.Controller == null) barManager.Controller = new BarAndDockingController();
barManager.Controller.PaintStyleName = "Skin";
barManager.Controller.LookAndFeel.UseDefaultLookAndFeel = false;
barManager.Controller.LookAndFeel.SkinName = "Office 2010 Blue";
barManager.ItemClick += HandleSendToPricingSheetClick;
barManager.Items.AddRange(new[] { new BarButtonItem(barManager, "Foo"), new BarButtonItem(barManager, "Bar"), new BarButtonItem(barManager, "Baz") });
var popupMenu = new PopupMenu { Manager = barManager };
foreach (var barItem in barManager.Items) popupMenu.ItemLinks.Add((BarItem)barItem);
popupMenu.ItemLinks[1].BeginGroup = true;
dropDownButtonSendToPricingSheet.DropDownControl = popupMenu;
}
2) This button is on a form. If the form loses focus (e.g. I click on Firefox), the pop-up menu still remains on-top. It won't go away until clicked.
Any suggestions would be much appreciated. Thanks for helping me deal with DevEx insanity.
I have solution to your second question.
You should add drop down button event handler as below:
dropDownButton1.LostFocus += new EventHandler(HidePopUp);
Handler method should be as below:
private void HidePopUp(object sender,object e)
{
dropDownButton1.HideDropDown();
}
For your second question, you should assign value to the bar manager property as:
BarManager manager = new BarManager();
manager.Form = this; // refers to current form
Find below link for reference
https://www.devexpress.com/Support/Center/Question/Details/Q274641
It is probably simpler to use DefaultLookAndFeel
Add this comp to your form and set the theme you'd like to use.
There is no need to set the theme for individual components.
defaultLookAndFeel1.LookAndFeel.SetSkinStyle("Office 2010 Blue");
Hi
I'm trying to add a new tab and my controls programatically to visual studio 2010.
Its creating tab but its not adding the controls to tab.
//Getting design time environment
DTE DesignTimeEnvironment = (DTE)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.10.0"), true);
//Getting tool box object
ToolBox VSToolBox = (ToolBox)DesignTimeEnvironment.Windows.Item("{B1E99781-AB81-11D0-B683-00AA00A3EE26}").Object;
ToolBoxTab MyTab = null;
string TabName = "MyComponents";
//checkin if Tab already exists
foreach (ToolBoxTab VSTab in VSToolBox.ToolBoxTabs)
{
if (VSTab.Name == TabName)
{
MyTab = VSTab;
break;
}
}
//If tab doesn't exist, creating new one
if (null == MyTab)
MyTab = VSToolBox.ToolBoxTabs.Add(TabName);
MyTab.Activate();
ToolBoxItem tbi = MyTab.ToolBoxItems.Add("FileBrowser",
#"MyComponents.FileBrowser, MyTestComps, Version=1.0.0.1, Culture=neutral, PublicKeyToken=2283de3658476795",
vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
DesignTimeEnvironment.Quit();
If i run as administrator its working fine, adding Controls to control library,
but when I try to add the library which is not in GAC its not working. It doesn't through any exception.
Ex:
ToolBoxItem tbi = MyTab.ToolBoxItems.Add("FileBrowser",
#"C:\MyComponents\MyTestComps.dll",
vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
It is working fine with the above code.
The only problem was I have to run the application as administrator rights.
Even this way also it is working.
ToolBoxItem tbi = MyTab.ToolBoxItems.Add("FileBrowser",
#"C:\MyComponents\MyTestComps.dll",
vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
or
http://blogs.msdn.com/b/quanto/archive/2009/06/12/how-do-i-deploy-a-toolbox-control-as-a-vsix.aspx
Currently, what I'm doing is this:
Using the built-in .NET PrintPreviewDialog
Attaching my own Click handler to the Print button, which allows for the user to select the printer before finally printing.
This all WORKS, HOWEVER, the OnprintToolStripButtonClick event is still sending the document to the default printer BEFORE the user gets to choose the actual printer and click Print (which works, but they're getting an extra copy on the default printer first from the old Handler).
Can I remove this built-in Click handler? I've tried the other methods mentioned on here in regards to using an EventHandlerList to remove the handlers, but it doesn't work for the built-in printing event. Here is a copy of my current code in case it helps clarify:
// ... Irrelevant code before this
private PrintPreviewDialog ppdlg;
ToolStrip ts = new ToolStrip();
ts.Name = "wrongToolStrip";
foreach (Control ctl in ppdlg.Controls)
{
if (ctl.Name.Equals("toolStrip1"))
{
ts = ctl as ToolStrip;
break;
}
}
ToolStripButton printButton = new ToolStripButton();
foreach (ToolStripItem tsi in ts.Items)
{
if (tsi.Name.Equals("printToolStripButton"))
{
printButton = tsi as ToolStripButton;
}
}
printButton.Click += new EventHandler(this.SelectPrinterAfterPreview);
// ... Irrelevant code afterwards omitted
// Here is the Handler for choosing a Printer that gets called after the
// PrintPreviewDialog's "Print" button is clicked.
private void SelectPrinterAfterPreview(object sender, EventArgs e)
{
frmMainPage frmMain = (frmMainPage)this.MdiParent;
if (frmMain.printDialog1.ShowDialog() == DialogResult.OK)
{
pd.PrinterSettings.PrinterName = frmMain.printDialog1.PrinterSettings.PrinterName;
pd.PrinterSettings.Copies = frmMain.printDialog1.PrinterSettings.Copies;
pd.Print();
}
}
Since you have access to the buttons in the toolstrip, remove the old print button and add your own. Assign the image from the default print button and you are all set. The code woudl look something like this:
ts.Items.Remove(printButton);
ToolStripButton b = new ToolStripButton();
b.ImageIndex = printButton.ImageIndex;
b.Visible = true;
ts.Items.Insert(0, b);
b.Click += new EventHandler(this.SelectPrinterAfterPreview);
I think replace buttons or use the Control Names from PrintPreviewDialog isĀ“nt a good option.
From Net1 to Net2 changes the name for the ToolBar. Next version can also change it or the name for other controls.
The PrintPreviewDialog is a very simple Form to encapsulate PrintPreviewControl.
You can build a new Form and put own buttons and implement your funcionality.
You can find some Dialogs for PrintPreview at Code-Project (CoolPrintPreviewDialog) An Enhaced PrintPreviewDialog.
On my PrvDialog, when user press the Print Button I show a PageSelDialog to allow the user select Range to Print (Current page, Some Pages, All-Pages, Cancel).
Other solution is override OnBeginPrint / suscribe event BeginPrint from PrintDocument.
Here you can show the PageSelDialog, cancel the Print and alter the DefaultPageSettings PrintRange, FromPage, ToPage.
For this Option you need know when is PrintToPrinter, Preview or Print From PrintButon.
PrintController.IsPreview, resolve for Preview Option.