如何使用ElementHost访问WPF控件?

rur96b6h  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(153)

我正在为Excel构建一个外接程序。我想使用WPF控件,所以我遵循了此教程https://learn.microsoft.com/en-us/visualstudio/vsto/using-wpf-controls-in-office-solutions?view=vs-2022我添加了一些选项卡控件以获得经验,我特别想在单击功能区中的按钮时满足某些条件时以编程方式转到选项卡项,我能够访问选项卡项的标题文本,但我无法修改它或将其设置为isSelected
这是我正在使用的代码:

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

下面是标记代码:

<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>

我已经调用了选项卡控件“MainTab”,以及两个选项卡项“Tab1”和“Tab2”,我不能用我当前的代码操作它们中的任何一个。

更新日期:

为了在Excel外接程序中使用WPF控件,根据文档,WPF用户控件必须由Windows窗体UI元素承载。在本例中,WPF用户控件位于Windows窗体用户控件内部。上面的链接解释了如何实现这一点。在上面的代码中,我使用了microsoft教程提供的变量名,但通过使用可以说更好的变量名,这段代码将阐明我所遵循的方法及其解决方案:

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
gfttwv5a

gfttwv5a1#

您正在uc中设定TabItemHeader属性,这是您建立的新控件,但没有将它加入增益集。
我想您应该将其设置为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

或者,您应该将uc添加到Globals.ThisAddIn.CustomTaskPanes,以便能够看到更改。

相关问题