【问题标题】:WPF ComboBox not firing SelectionChanged event if placed at the bottom of Word AddIn如果放置在 Word AddIn 的底部,WPF ComboBox 不会触发 SelectionChanged 事件
【发布时间】:2015-06-03 07:18:04
【问题描述】:

我正在开发 Office Word AddIn 并使用 WPF 控件作为 WinForms UserControl 内的用户界面作为容器(在 ElementHost 控件内)。

我注意到 ComboBox 的问题是,如果将靠近 Word 应用程序底部的项目放置在 AddIn 的底部,它不会触发 SelectionChanged 事件。例如,我可以单击并选择第一个列出的项目(如果幸运的话),否则 ComboBox 下拉菜单(弹出)将被关闭,并且不会触发 SelectionChanged 事件。相反,Word 会执行一些操作,例如缩放或更改页面布局 - 如果 Addin 位于右侧,则这些操作位于 Word 应用程序的右下方。

我发现的唯一解决方法是“向上”使用 ComboBox 弹出窗口。在这种情况下,事件会很好地触发。正如我所说,这是一种解决方法,我希望看到一些更智能的解决方案。

P.S.:如果我使用 WinForms ComboBox 控件,将其放在底部不会导致此问题 - SelectedIndexChanged 事件按预期工作。

谢谢

编辑:我添加了一些非常基本的示例代码。

示例代码:WpfControl.xaml - UI

<UserControl x:Class="WordAddIn.WpfControl" 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="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="100*"></RowDefinition>
            <RowDefinition Height="40"></RowDefinition>
        </Grid.RowDefinitions>

        <ComboBox x:Name="cboItems" Grid.Row="1" Margin="10,10,10,10"
                  DisplayMemberPath="NAME"
                  SelectionChanged="cboItems_SelectionChanged"/>
    </Grid>
</UserControl>

示例代码:WpfControl.xaml.cs - 隐藏代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WordAddIn
{
    /// <summary>
    /// Interaction logic for WpfControl.xaml
    /// </summary>
    public partial class WpfControl : UserControl
    {
        public class Item
        {
            public int ID { get; set; }
            public string NAME { get; set; }
        }

        public WpfControl()
        {
            InitializeComponent();

            List<Item> itemList = new List<Item>();

            for (int i = 1; i < 11; i++)
            {
                itemList.Add(new Item { ID = i, NAME = "Item " + i });
            }

            cboItems.ItemsSource = itemList;
        }

        private void cboItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems != null && e.AddedItems.Count > 0)
            {
                var item = ((object[])(e.AddedItems)).ToList().FirstOrDefault() as Item;

                MessageBox.Show("Item: " + item.NAME + " clicked");

                e.Handled = true;
            }

            e.Handled = false;
        }
    }
}

包含元素宿主和作为元素宿主子元素的 WpfControl 的 WpfContrainer 被添加为 Addin on button 点击​​ Word 功能区。

示例代码:RibbonWord.cs

private void btnTest_Click(object sender, RibbonControlEventArgs e)
{
    WpfContainer wpfContainer = new WpfContainer();

    var wpfContainerPane = Globals.ThisAddIn.CustomTaskPanes.Add(wpfContainer, "AddIn");

    wpfContainerPane.Visible = true;
}

【问题讨论】:

  • 请添加您的代码。
  • 我用示例代码更新了问题(不是 ComboBox 的倒置样式的可能解决方案)。不太确定它会有什么帮助,因为它是非常非常基本的东西,但在这里。提前谢谢。

标签: c# wpf combobox vsto


【解决方案1】:

我有同样的问题。当下拉菜单位于 wpf 之外时,SelectionChanged 不起作用。尝试以这种方式更改您的代码

Xaml:

   <ComboBox x:Name="cboItems" 
             Grid.Row="1" 
             Margin="10,10,10,10"
             DisplayMemberPath="NAME"
             SelectionChanged="cboItems_SelectionChanged"
             DropDownOpened="ComboBox_OnDropDownOpened"
             DropDownClosed="ComboBox_OnDropDownClosed" />

后面的代码:

namespace WordAddIn
{        
    public partial class WpfControl : UserControl
    {
        // your code

        private DispatcherFrame dispatcherFrame;           

        private object DispatcherOperationBegin(object arg)
        {
            dispatcherFrame = new DispatcherFrame();
            Dispatcher.PushFrame(dispatcherFrame);
            return null;
        }

        private void ComboBox_OnDropDownOpened(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(DispatcherOperationBegin), null);
        }

        private void ComboBox_OnDropDownClosed(object sender, EventArgs e)
        {
            dispatcherFrame.Continue = false;
        }
    }
}

有关DispatcherFrame的更多信息,您可以找到here

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 2014-05-02
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    相关资源
    最近更新 更多