Excel buttons to call WPF windows - c#

I have a CSharp (.NET) application that has created an add-in with a ribbon in Excel. I have buttons in the ribbon. I want to be able to click on the buttons, and open WPF windows.
The code looks like
private void OnNewButtonAction(object sender, RibbonControlEventArgs e)
{
var window = new View.MyWindow()
{
DataContext = new ViewModel.MyViewModel(),
};
window.Show();
}
Where MyWindow is a class of type System.Windows.Window. MyWindow has its own xaml file, which has radio buttons, text fields etc. When I try to run this - and click on the button, I get an XML parse exception as - "'Provide value on 'System.Windows.StaticResourceExtension' threw an exception".
Is it possible to invoke wpf windows from excel add-ins? What am I doing wrong?
Edit: I have already looked at
Using WPF Controls in Office Solutions and it doesn't work. And it adds a separate pane to excel, which is not what I am looking at.

You should use Excel-DNA. Its a really useful piece of software designed just for things like this, it helps to implement Excel with WPF, and you shouldn't have any problems again.
you can get it Here
If however you don't want that there is a step by step tutorial here on how to do it.
You may try to define a WPF window as a custom control and add it to the custom pane of the word. Have a look at the following link, pleases:
Using WPF Controls in Office Solutions
You may have a look at this link as well:
Office 2007 Excel Addin - WPF ComboBox Collapses when Expanded
The common way we add WPF control to custompane is:
Create an Excel add-in project
Add user control (WPF) name UserControl1 and add reference to System.xaml
Code the WPF control and Build the project successfully
Add User Control from Window Form collection, named the control as UserControl2
Drag and drop a UserControl1 to UserControl2, assign the position as you like
Code the ThisAddIn.cs in this way:
UserControl1 myWPF;
UserControl2 winformControl;
Microsoft.Office.Tools.CustomTaskPane pane;
System.Windows.Forms.Integration.ElementHost myHost;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
myWPF = new UserControl1();
winformControl = new UserControl2();
pane = CustomTaskPanes.Add(winformControl, "WPFControl");
pane.Visible = true;
pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
}
We can use the button to control the pane's visible property.

Related

How to create tab pages content dynamically in windows forms?

I am using windows form to build an app that draws the form controls based on the connected device dynamically. So I have a tab control and when the user select tab3 for instance the tab page content will be drawing based on connected device for example add two text boxes and a button. How can I do this. I would like also to know how to position those controls after they are created.
private void tabPage3_Click(object sender, EventArgs e)
{
TextBox text = new TextBox();
this.tabPage3.Controls.Add(text);
}
As you just stated, you create your Controls like in your example. Positioning is achieved by the Left and Top Properties of your freshly created control. BUT, my advise is, it will be easier to use predefined UserControls and add them dynamically, because I think you don't have nearly unlimited types of devices.
If you are curious how Visual Studio Designer is creating those code, just look up Designer.cs in InitializeComponent()

Powerpoint AddIn

I am new to powerpoint add in and looking to add custom task pane.
https://msdn.microsoft.com/en-us/library/Microsoft.Office.Tools.CustomTaskPane(v=vs.110).aspx
from Above link you can add custompane by using
this.CustomTaskPanes.add()
I cannot find CustomTaskPanes in the intellisense when trying to do it from ribbon control click.
Any ideas?
The CustomTaskPanes collection is a property on the ThisAddIn class.
So, you will be able to access it within the ThisAddIn_Startup method using the "this." syntax. If you're not seeing the collection in intellisense/autocomplete.
The issue may have arised due to some possibilities like :
You're not using VSTO(Visual Studio Tools for Office) 2005 SE.
You're using VSTO 2005 SE but you installed on top of a previous VSTO v3 CTP which was not completely removed.
You're building an add-in for an application that does not support custom task panes (all the Office 2003 apps, Visio 2007).
That's a sample code to create a "Log Pane" and load a control into it. It's defined as a new property of ThisAddin.cs class, so you can invoke it by Global.ThisAddin.LogPane
private OfficeTools.CustomTaskPane _logPane;
public OfficeTools.CustomTaskPane LogPane
{
get
{
if(_logPane==null)
{
//my winforms component to load into the pane
var logViewerComp = new LogViewerComp();
_logPane = CustomTaskPanes.Add(logViewerComp, "Log Pane");
//makes the log component fill the all pane size
logViewerComp.Dock = DockStyle.Fill;
//sets the opening position of the pane into PPT view
_logPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionBottom;
//does something when the pane shows/hides
//in this case refreshes the Ribbon to enable/disable
//the toggle button status related to the pane
_logPane.VisibleChanged += (snd, ev) =>
{
Ribbon.Reload();
};
}
return _logPane;
}
}
Note: when you create a Pane it belongs to the all app and it is shared between all presentations the user opens.

Set the Button Text according to Resource File in Visual Studio 2013

I am an Amateur Visual C# Programmer.
I want to implement the concept of I18N in my project.
(Similar to strings.xml in Android)
I have added 2 String Resources in my Resource File.
And I have added 2 Buttons in my form.
Now, I want the text of the Button to be the string value from the Resource file.
Please help.
Adhish
If you are using windows form, you can use this procedure.
Open the properties menu of the form in the design. Select the option "Language" and choose the language that you want.
Selecting a different language will create automatically a new file resource with the label for the language selected.
The file .resx will the same name of the form plus the initial of the language used.
It really depends on your UI framework. The following solution is for WinForms, but you can implement it (without MVVM) in WPF as well.
Create a button in the designer.
Register to the Load event of the form by double clicking it. (Right click on the form => properties => click the events button => search for the Load event)
In the load event, initialize the text of the button with the string from the resources.
Your code should look something like this:
private void Form1_Load(object sender, EventArgs e)
{
button1.Text = MyResources.ButtonText;
}

Custom task pane with multiple open workbooks

I've successfully implemented the Microsoft sample "Walkthrough: Synchronizing a Custom Task Pane with a Ribbon Button" found here:
http://msdn.microsoft.com/en-us/library/bb608590.aspx
Initially I ran into a problem with the task pane not showing, which turned out to be the result of some conflict between my add-in and Microsoft's "Analysis Toolpack". Once I disabled Analysis Toolpack the custom task pane began to show and hide as expected.
I then wrote some code to alter cells in a selected range when the user presses a button. That seemed to work just fine -- until I opened another workbook! Each workbook window got its own add-in ribbon, but when I clicked the toggle button to open/close the custom task pane it would only open/close the custom task pane for the first window that was created. This is regardless of which window I click the toggle button in.
The code instantiates the CustomTaskPane object in ThisAddIn_Startup (just like in the example code). The only thing I've added really is the button action in the UserControl:
using xl = Microsoft.Office.Interop.Excel;
namespace SynchronizeTaskPaneAndRibbon
{
public partial class TaskPaneControl : UserControl
{
public TaskPaneControl()
{
InitializeComponent();
}
private void actionButton1_Click(object sender, EventArgs e)
{
xl.Range selection_rng = Globals.ThisAddIn.Application.Selection;
foreach (xl.Range cell in selection_rng.Cells)
{
if (cell.Value is string)
{
string v = cell.Value;
cell.Value = v + "*";
}
}
}
}
}
The rest of the code is just as it is in the example.
Is there a way to change the example so that it will work for open multiple workbooks? What I want is for the same Add-In to appear in each workbook window, with the same Ribbon and with the same Custom Pane. And, of course, to have any ribbon actions (such as a button press) route to the custom task pane that appears within the same window.
Yes there is another example on MSDN which talks about managing custom taskpanes in multiple documents. Do note that this is from the perspective of Word/InfoPath but the underlying idea will be same for Excel too.
Broadly speaking, you need to add a new taskpane for current workbook if it does not have one. So move the adding of custom taskpane logic from Addin startup to ribbon button click event. Doing this in button click event gives you opportunity to add a new taskpane to current document when ribbon is clicked.
Link: https://msdn.microsoft.com/en-us/library/bb264456(v=office.12).aspx?f=255&MSPPError=-2147217396#Anchor_2
Putting the useful code snippets below in case the link goes dead in future:
//Add a custom taskpane to active Word document
public void AddCalendarTaskPane(Word.Document doc)
{
ctpCalendar = this.CustomTaskPanes.Add(new CalendarControl(),
"Select a date", doc.ActiveWindow);
ctpCalendar.Visible = true;
}
Instead of removing, I recommend hiding the taskpane by toggling Visible flag to false but YMMV. Hope this helps.

How to get the Custom Task Pane Object on the Ribbon control Class

Developing a Excel vsto project, how could I handle the Custom Task Pane in the Class which is a Ribbon Control.
For example, I would like to show the Custom Task Pane when I click the button of the Ribbon Control.
Dora
I assume you are working with an Excel VSTO add-in, with the Ribbon Visual Designer. You can achieve what you want by making your custom Task Pane accessible via a property on your Add-In:
public partial class ThisAddIn
{
private CustomTaskPane taskPane;
internal CustomTaskPane TaskPane
{
get
{
return this.taskPane;
}
}
... and adding a button in your Ribbon, and adding an event handler for the click event, accessing the add-in via Globals:
private void MyRibbonButton_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.TaskPane.Visible = true;
}
I wrote a post a while back which describes the process, you may find it useful.
This is also feasible using the xml ribbon.
This can be accomplished by having a Win Forms user control.
I've worked on a project where we had to extend MS Word and needed this functionality, but the same example will apply to Excel.
Another interesting way I stumbled upon on the net is to have a Windows user control and host a WPF user control within the Windows control!
This ofcourse allows you to take advantage of all the awesome tools you get with WPF, here is an example:
1)Drop a ToggleButton on a Ribbon(Visual Designer).This will be used to show hide the task pane.
Using ToggleButton is a good choice as it appears highlighted when pressed down.
2)Add below code to the click event of the ToggleButton
Globals.ThisAddIn.TaskPane.Visible = ((RibbonToggleButton)sender).Checked;
3)Add a reference from your project to the following assembly - WindowsFormsIntegration
4)In your ThisAddIn.cs add the two using directives listed below:
using Microsoft.Office.Tools;
using System.Windows.Forms.Integration;
5)Add two user controls
5.1)User control (name - taskPaneControl1)
5.2)User control(WPF),(name - con)
Using the names I've used will help when copying/pasting the code below but by any means change it if you wish to
6)Add below code to the ThisAddIn.cs class
public CustomTaskPane TaskPane
{
get{return taskPaneValue;}
}
private TaskPaneControl taskPaneControl1;
private CustomTaskPane taskPaneValue;
private WpfControl con;
internal void AddTaskPane()
{
ElementHost host = new ElementHost();
con = new WpfControl();
host.Child = con;
host.Dock = DockStyle.Fill;
taskPaneControl1 = new TaskPaneControl();
taskPaneControl1.Controls.Add(host);
taskPaneValue = this.CustomTaskPanes.Add(taskPaneControl1, "My Taskpane");
taskPaneValue.Visible = true;
}
6)Add the two code below to the Startup event in your ThisAddIn.cs
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
AddTaskPane();
taskPaneValue.Visible = false;
}
When an MS Office Application is opened the task pane will be hidden toggle the Visible property to change this in the Startup event.
Navigate to the ToggleButton and press it a few times to make sure the task pane is showing as expected
Also have a look at the following link most of my code came from here - http://xamlcoder.com/cs/blogs/joe/archive/2007/07/17/using-wpf-with-vsto-office-2007.aspx
This is a difficult challenge since the Ribbon and Task Panes are separate entities. One of the main challenges is that there is only one instance of the Ribbon class and multiple instances of the task pane for each inspector. To this properly requires some advanced understanding of the Office internals.
The solution also depends on whether you are using the Ribbon XML or Ribbon Designer. Which approach are you using?

Categories

Resources