I'm building an Add-in for Excel. I wanted to use WPF controls, so I followed this tutorial https://learn.microsoft.com/en-us/visualstudio/vsto/using-wpf-controls-in-office-solutions?view=vs-2022 I added some tab controls to get my feet wet, I particularly wanted to programmatically go to a tab item if some condition was met upon clicking a button in the Ribbon, I was able to access the header text of the tab item, but I was not able to modify it or set it to isSelected.
This is the code that I'm using:
Imports Microsoft.Office.Tools
Imports Microsoft.Office.Tools.Ribbon
Public Class Ribbon1
Private myUserControl1 As MyUserControl
Private myCustomTaskPane As CustomTaskPane
Private Sub btnCheck_Click(sender As Object, e As RibbonControlEventArgs) Handles btnCheck.Click
' Show the taskpane
myUserControl1 = New MyUserControl
myCustomTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl1, "Test addin")
myCustomTaskPane.Width = 500
myCustomTaskPane.Visible = True
Dim uc As New UserControl1
' Check if there's a table
If isThereATable() Then
MsgBox("There is")
MsgBox(uc.Tab2.Header) ' works
uc.Tab2.Header = "new header" ' does not work
Else
MsgBox("There is not")
End If
End Sub
End Class
And this is the markup code:
<UserControl x:Class="UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AutoTable"
mc:Ignorable="d"
d:DesignHeight="450" Width="500">
<Grid Width="500">
<TabControl BorderThickness="1" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Left" Width="500" Name="MainTab">
<TabItem Header="Init" Name="Tab1" >
<Grid Background="#FFE5E5E5" Margin="0">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="The following button should create a table." VerticalAlignment="Top" FontSize="16" Margin="10,10,0,0"/>
<Button Content="Create table" HorizontalAlignment="Left" Margin="5,60,0,0" VerticalAlignment="Top" Width="100" Click="Button_Click" Height="30" FontSize="14"/>
</Grid>
</TabItem>
<TabItem Header="CC" Name="Tab2" >
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
</Grid>
</UserControl>
I have called the tab control "MainTab", and the two tab items "Tab1" and "Tab2", I can not manipulate any of them with my current code.
UPDATE:
In order to use WPF controls in an Excel Add-In, the WPF User Control must be hosted by a Windows Forms UI Element, according to the docs. In this case, the WPF User Control is inside a Windows Forms User Control. The link above explains how this is done. In the code above, I was using variable names provided by microsoft's tutorial, but by using arguably better variable names, this piece of code would clarify the approach I was following and its solution:
Public Class Ribbon1
Private ThisUserControl As UserControlWF
Private ThisTaskPane As Microsoft.Office.Tools.CustomTaskPane
Private Sub ShowTaskPane_Click(sender As Object, e As RibbonControlEventArgs) Handles ShowTaskPane.Click
ThisUserControl = New UserControlWF
'CustomTaskPanes can only add Windows Forms UI elements, a WPF User Control throws an error
ThisTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(ThisUserControl, "Title")
ThisTaskPane.Width = 510
ThisTaskPane.Visible = True
' Just to test if a condition is true after it loads the task pane
If isThereATable() Then
MsgBox("There is a table")
ThisUserControl.UserControlWPF1.Tab2.Header = "Different Header" 'Original header name is "TabItem2"
ThisUserControl.UserControlWPF1.Tab2.IsSelected = True 'Tab1 is selected by default
' In my first approach, I was initializing another instance of the WPF control
' instead of using the one that was already initialized:
' Dim uc As New UserControlWPF
' MsgBox(uc.Tab2.Header) ' <- it worked
' uc.Tab2.Header = "Different Header" ' <- it did not work
' That's why I was able to access the Header from the class, but I couldn't
' modify the header that was already loaded
Else
MsgBox("There is no table")
End If
End Sub
End Class
CodePudding user response:
You are setting the Header
property of the TabItem
in uc
, which is a new control that you create without adding it to the add-in.
I guess you should set it in myUserControl1
:
Private Sub btnCheck_Click(sender As Object, e As RibbonControlEventArgs) Handles btnCheck.Click
' Show the taskpane
myUserControl1 = New MyUserControl
myCustomTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl1, "Test addin")
myCustomTaskPane.Width = 500
myCustomTaskPane.Visible = True
' Check if there's a table
If isThereATable() Then
MsgBox("There is")
MsgBox(myUserControl1.Tab2.Header) ' works
myUserControl1.Tab2.Header = "new header" ' does not work
Else
MsgBox("There is not")
End If
End Sub
Or you should add uc
to Globals.ThisAddIn.CustomTaskPanes
to be able to see the change.