none
WPF ComboBox behavior affected when hosted in a task pane RRS feed

  • Question

  • I have a VSTO Excel 2010 ribbon add-in that has a task pane. The task pane programmatically adds a WPF user control, which in turn contains an ElementHost that contains a simple user control with a single WPF ComboBox.  (We have other task panes that do not have comboboxes, and they are working just fine.)

    I've encountered problems with selecting items from the WPF ComboBox in the task pane that I don't have when using the same WPF ComboBox in, say, a WPF Application.  For example:

    WPF Application:

            public MainWindow()
            {
                InitializeComponent();
    
                comboBox1.Items.Add("One");
                comboBox1.Items.Add("Two");
                comboBox1.Items.Add("Three"); 
            }
    
            private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                textBlock1.Text = comboBox1.SelectedItem.ToString();
            }

    Selecting the last item behaves as expected:

    Same control hosted in task pane:

    Inside the task pane, I can select the first or second item. But the third item, while visible, is not selectable.

    Is there a workaround/fix for this behavior? 

    In my Web searching so far, I've seen a few references to removing the WS_CHILD style for the task pane as a way to correct odd control behaviors -- but these were regarding third-party controls, not standard WPF controls like the ComboBox.  And it was not clear to me how, specifically, one could remove the WS_CHILD style for a standard VSTO Excel 2010 task pane's hosted controls.

    Saturday, February 18, 2012 12:43 AM

All replies

  • Hi,

    I'm sorry,  the issue can't be reprodude on my side, would you like to post you xaml code as well, which I think is also related to this issue?

    In addition, which version of .NET framework the project uses?

    I look forward to hearing of you soon.


    Calvin Gao[MSFT]
    MSDN Community Support | Feedback to us

    Monday, February 20, 2012 5:35 AM
    Moderator
  • Hi Calvin,

    The .NET Framework is 4.0.

    Here's the complete code:

    ComboUserControl.xaml:

    <usercontrol height="auto" mc:ignorable="d" padding="3" width="auto" x:class="TaskPaneComboTest.ComboUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <grid height="auto" margin="5">
            <stackpanel orientation="Vertical">
            <stackpanel orientation="Horizontal">
            <label content="Selected:" height="auto" horizontalalignment="Left" name="label1" verticalalignment="Center"></label>
            <textblock height="auto" horizontalalignment="Left" name="textBlock1" text="TextBlock" verticalalignment="Center"></textblock>
            </stackpanel>
                <stackpanel orientation="Horizontal">
            <combobox height="auto" horizontalalignment="Left" iseditable="False" name="comboBox1" selectionchanged="OnSelectionChanged" verticalalignment="Top" width="120"></combobox>
            </stackpanel>
            </stackpanel>
        </grid>
    </usercontrol>

    ComboUserControl.xaml.cs:

        /// <summary>
        /// Interaction logic for ComboUserControl.xaml
        /// </summary>
        public partial class ComboUserControl : UserControl
        {
            public ComboUserControl()
            {
                InitializeComponent();
                comboBox1.Items.Add("One");
                comboBox1.Items.Add("Two");
                comboBox1.Items.Add("Three");
            }
    
            private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                textBlock1.Text = comboBox1.SelectedItem.ToString();
            }
        }

    ComboTaskPanelUserControl.cs:

        public partial class ComboTaskPaneUserControl : UserControl
        {
            public ComboTaskPaneUserControl()
            {
                InitializeComponent();
    
                ElementHost host = new ElementHost();
                host.Dock = DockStyle.Fill;
    
                // Create the WPF UserContol
                ComboUserControl uc = new ComboUserControl();
                host.Child = uc;
                this.Controls.Add(host);
            }
        }
    }

    ThisAddIn.cs:

        public partial class ThisAddIn
        {
            private RibbonComboTest _taskPaneRibbon;
            internal Microsoft.Office.Tools.CustomTaskPane SheetNavigationTaskPane = null;
            private ComboTaskPaneUserControl _comboUserControl = null;
    
            protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
            {
                _taskPaneRibbon = new RibbonComboTest();
                return _taskPaneRibbon;
            }
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                #region Task Pane
                _comboUserControl = new ComboTaskPaneUserControl();
                SheetNavigationTaskPane = this.CustomTaskPanes.Add(_comboUserControl, "Task Pane Combo Test");
                SheetNavigationTaskPane.Visible = true;
                SheetNavigationTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionBottom;
                SheetNavigationTaskPane.Height = 90;            
                #endregion
            }
    
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }
    
            #region VSTO generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
            
            #endregion
        }

    Create an Excel 2010 add-in with the above code. The task pane should appear at startup. Test it as follows:

    1. Set a breakpoint for OnSelectionChanged.

    2. Using the mouse, select One or Two from the combobox.  OnSelectionChanged is fired. Using the mouse, attempt to select Three from the combobox. It is never selected (the previous selection remains), and OnSelectionChanged is NOT fired.

    3. Now, use the mouse to place focus on the combobox, but use the DownArrow key to highlight any of the three items, and then press the Return key. OnSelectionChanged is fired every time.

    The issue is that users cannot be expected to use arrow keys and Return to select the last combobox item.

    Summary:  Test using the same steps above when you build the same combobox in a WPF application rather than an add-in task pane. The selection behavior is different. 

    Let me know if you still have problems reproducing this issue.

    Thanks!

    Anonymous9748


    Tuesday, February 21, 2012 2:21 PM
  • I have exactly the same problem with my Word 2007 or 2010 Add-In. A WPF control with a combobox hosted via ElementHost inside a Custom Task Pane (CTP). When trying to select an item displayed outside the boundaries of the CTP container, it is not recognized (BTW: keyboard navigation is working).

    Instead of the combobox, the click is recognized by winwords content window. In the following example Word reacts like I had clicked on the ruler.

    Selection with the mouse is not recognized.

    This is a short and simple code sample in order to reproduce that behavior.

    1. ThisAddIn.vb

    Imports System.Diagnostics
    Imports Microsoft.Office.Interop.Word
    Imports System.Windows.Forms
    
    
    Public Class ThisAddIn
      ''' <summary>
      ''' Access my ribbon from the addin
      ''' </summary>
      ''' <remarks></remarks>
      Private _ribbonFunctionalityAndUI As DemoRibbon
    
      ''' <summary>
      ''' AddIn is loading
      ''' </summary>
      ''' <remarks></remarks>
      Private Sub ThisAddIn_Startup() Handles Me.Startup
        CreateTaskPaneControl(CreateElementHostForWPFControl(New TestPanel()))
      End Sub
      ''' <summary>
      ''' 
      ''' </summary>
      ''' <remarks></remarks>
      Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
        'MsgBox("ThisAddIn_Shutdown")
      End Sub
      ''' <summary>
      ''' Enable Word to access the ribbon and all callback functions. <br/>
      ''' This function is called before <see cref="ThisAddIn.ThisAddIn_Startup"/>
      ''' </summary>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Protected Overrides Function CreateRibbonExtensibilityObject() As Microsoft.Office.Core.IRibbonExtensibility
        'MsgBox("CreateRibbonExtensibilityObject")
        _ribbonFunctionalityAndUI = New DemoRibbon()
        Return _ribbonFunctionalityAndUI
      End Function
    
      Private Sub CreateTaskPaneControl(control As System.Windows.Forms.UserControl)
        Dim customTaskPane As Microsoft.Office.Tools.CustomTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(control, "Sample Control")
        customTaskPane.Visible = True
        customTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionTop
        customTaskPane.Height = 100
      End Sub
    
      Public Shared Function CreateElementHostForWPFControl(control As System.Windows.UIElement) As System.Windows.Forms.UserControl
        Dim userControl = New System.Windows.Forms.UserControl()
        Dim host As New System.Windows.Forms.Integration.ElementHost() With { _
          .Dock = System.Windows.Forms.DockStyle.Fill _
        }
        host.Child = control
        userControl.Controls.Add(host)
        Return userControl
      End Function
    
    End Class
    

    2. TestPanel.xaml

    <UserControl x:Class="TestPanel"
                 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" mc:Ignorable="d" 
                 d:DesignHeight="93" d:DesignWidth="752">
        <Grid>
            <WrapPanel Name="FreitextWrapPanel" Orientation="Horizontal" Grid.Column="0">
                <ComboBox Name="Dummy" Height="18" Width="94" >
                    <ComboBoxItem Content="Coffie"></ComboBoxItem>
                    <ComboBoxItem Content="Tea"></ComboBoxItem>
                    <ComboBoxItem Content="Orange Juice"></ComboBoxItem>
                    <ComboBoxItem Content="Milk"></ComboBoxItem>
                    <ComboBoxItem Content="Iced Tea"></ComboBoxItem>
                    <ComboBoxItem Content="Mango Shake"></ComboBoxItem>
                    <ComboBoxItem Content="Soda"></ComboBoxItem>
                </ComboBox>
            </WrapPanel>
        </Grid>
    </UserControl>
    

    3. TestPanel.xaml.vb

    Imports System.Windows.Controls
    Imports System.Windows.Input
    Imports System.Windows
    
    Public Class TestPanel
      Inherits System.Windows.Controls.UserControl
      Private Sub Dummy_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles Dummy.SelectionChanged
        Dim comboBox As ComboBox = sender
    
        Diagnostics.Trace.WriteLine(comboBox.SelectedValue)
        MessageBox.Show("You have chosen " & comboBox.SelectedItem.ToString)
      End Sub
    End Class
    

    I could also provide the full visual studio solution (114092211822217 Repro.zip, 119 kb).

    Tuesday, December 16, 2014 9:28 AM
  • We're struggling with the same issue — any chance you've solved this since you posted?
    Friday, February 27, 2015 8:57 PM
  • Ditto.  Any response on this??
    Monday, June 8, 2015 7:21 PM