Cant select items in a WPF combobox(VSTO Addin) if they are outside the parent window

Matt V 21 Reputation points
2021-03-11T21:22:09.757+00:00

When using a Combobox in a WPF UserControl via ElementHost for a VSTO AddIn, the Combobox items that are outside of the parent Office application cannot be selected.

In the clip below, the blue area is a WPF UserControl inside an ElementHost and you will see that '11111111' gets selected, but 'CCCCCCCC' does not because it is outside of the Outlook window. The second Combobox is just a plain WinForms Combobox and all items work fine, even outside the parent Outlook window.

76858-2021-03-11-14-45-23.gif

The Addin in the clip is just a super simple VSTO addin with a single CustomTaskPane, a WPF UserControl hosted inside an ElementHost(blue box), and then a plain WinForms Combobox.

I also tested creating a regular .Net WinForms Desktop application with this same WPF UserControl inside an ElementHost, and it works fine. So this leads me to believe its something with VSTO, but I have been unable to find any good info on how to fix.

Has anyone ran across this and know if it can be fixed? Telling users to just maximize their Outlook window worked for a little while, but not an ideal solution.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,676 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,278 questions
Office Development
Office Development
Office: A suite of Microsoft productivity software that supports common business tasks, including word processing, email, presentations, and data management and analysis.Development: The process of researching, productizing, and refining new or existing technologies.
3,509 questions
0 comments No comments
{count} votes

Accepted answer
  1. gekka 6,686 Reputation points MVP
    2021-03-13T12:15:35.793+00:00
    namespace OutlookAddIn1
    {
        using System;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Controls;
    
        using System.Windows.Input;
        using System.Windows.Media;
    
        public partial class VSTOComboBoxTestUserControl : System.Windows.Controls.UserControl
        {
            public VSTOComboBoxTestUserControl()
            {
                InitializeComponent();
    
                var combo = new ComboBox();
                combo.DropDownOpened += ComboBox_DropDownOpened;
    
                var s = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                foreach (char c in s)
                {
                    combo.Items.Add(new string(c, 20));
                }
    
                this.Content = combo;
            }
    
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            private static extern short GetAsyncKeyState(int virtualKeyCode);
            private const int VK_LBUTTON = 1;
    
            private async void ComboBox_DropDownOpened(object sender, EventArgs e)
            {
                var combo = (System.Windows.Controls.ComboBox)sender;
                if (Mouse.Captured == combo)
                {
                    while (combo.IsDropDownOpen && Mouse.Captured == combo)
                    {
                        if (Mouse.LeftButton == MouseButtonState.Released)
                        {
                            combo.LostMouseCapture += Combo_LostMouseCapture;
                            return;
                        }
                        await Task.Delay(1);
                    }
                }
            }
    
            private void Combo_LostMouseCapture(object sender, MouseEventArgs e)
            {
                var combo = (ComboBox)sender;
                combo.LostMouseCapture -= Combo_LostMouseCapture;
    
                if (Mouse.Captured != null)
                {
                    return; //Not Supported
                }
    
                var esckey = (GetAsyncKeyState(System.Windows.Input.KeyInterop.VirtualKeyFromKey(Key.Escape)) & 0x8000) == 0x8000;
                var lbutton = (GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0x8000;
    
                if (esckey || !lbutton)
                {
                    return;
                }
    
                var d = e.MouseDevice.Target as DependencyObject;
                while (d != null)
                {
                    var comboItem = d as ComboBoxItem;
                    if (comboItem != null)
                    {
                        var index = combo.ItemContainerGenerator.IndexFromContainer(comboItem);
                        if (index >= 0)
                        {
                            if (comboItem.IsEnabled && comboItem.IsHitTestVisible && comboItem.IsMouseOver)
                            {
                                if (combo.SelectedIndex != index)
                                {
                                    combo.SelectedIndex = index;
    
                                }
                                return;
                            }
                        }
                    }
                    d = VisualTreeHelper.GetParent(d);
                }
    
            }
        }
    }
    
    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Юрий 1 Reputation point
    2022-04-27T06:37:29.127+00:00

    Thank you very match! I had this problem after upgrading to .NET 5.

    0 comments No comments