错误:不能selectDatePicker上的浮动VSTO加载项之外的date

这里logging与微软的问题 – Repro可以下载: https : //connect.microsoft.com/VisualStudio/feedback/details/741454/value-change-event-doesnt-fire-for-datetimepicker-controls-used-在-VSTO-插件

如果将DateTimePicker放入Excel VSTO浮动加载项中,并且在日历下拉时将其放置,则它位于加载项边缘之外,请参阅此处:

在这里输入图像说明

select绿色环绕的任何date如预期,但点击任何红色的date,它只是closures日历下拉,并没有设置date!

有谁知道我可以解决这个问题?

编辑

这个SO用户遇到了使用WPF的问题: VSTO WPF ContextMenu.MenuItem在没有提出的TaskPane之外单击

在这里输入图像说明

这个问题的答案表明这个问题被报告连接了一段时间,但仍然没有与VSTO 4.0 SP1的解决scheme: https : //connect.microsoft.com/VisualStudio/feedback/details/432998/excel-2007-vsto-custom-任务窗格与- WPF的上下文菜单具有焦点,问题

其中一个解决方法是使用DispatcherFrame来抽取消息并为菜单订阅GotFocusEvent和LostFocusEvent。 http://blogs.msdn.com/b/vsod/archive/2009/12/16/excel-2007-wpf-events-are-not-fired-for-items-that-overlap-excel-ui-for- wpf-context-menus.aspx但是这是所有菜单的WPF代码不是Winform DateTimePicker的解决scheme。

Microsoft Connect Repro:

新build项目> Excel 2010加载项

private void ThisAddIn_Startup(object sender, System.EventArgs e) { //setup custom taskpane MyTaskView = new TaskPaneView(); MyTaskView.currentInstance = Globals.ThisAddIn.Application; MyTaskPane = this.CustomTaskPanes.Add(MyTaskView, "MyTaskView"); MyTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating; MyTaskPane.DockPositionRestrict = MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange; MyTaskPane.Visible = true; } 

文件菜单>添加>新build项目>类库>名为TaskPane

然后在TaskPane项目中创build一个名为TaskPaneView的用户控件

 public partial class TaskPaneView : UserControl { public TaskPaneView() { InitializeComponent(); } public Microsoft.Office.Interop.Excel.Application currentInstance { get; set; } public TaskPaneCtrl getTaskPaneCtrl { get { return this.taskPaneCtrl1; } } } 

接下来使用DateTimePicker创build一个用户控件,确保Calendar控件位于用户控件的右下angular

 public partial class TaskPaneCtrl : UserControl { public TaskPaneCtrl() { InitializeComponent(); } } 

F5并单击日历控件,现在尝试select任务窗格区域外部的date。 没有值更改事件触发,它的行为就像日历之外的点击!

注意:我尝试了一个掉落下来的控件,但是它的事件不会消失!

“浮动”是这里问题的关键。 从来没有问题的是,你依靠Excel中的消息泵来发送Windows消息,这些消息使这些控件响应input。 这在WPF中和WinForms一样错误,他们有自己的调度循环,在消息传递到窗口之前过滤消息。 关键的事情,当他们各自的调度不使用时出现问题,如tabbing和快捷键击。

然后一些,这种问题将由Excel在分派消息之前进行自己的过滤。 我猜想在一个反恶意软件function,微软永远担心与Office应用程序搞乱的程序。

Winforms解决scheme与WPF解决方法是一样的,您需要抽取自己的消息循环。 这需要一些手术,DateTimePicker是不会合作,因为它不允许其DropDown事件被取消,并在日历已经显示引发。 该解决方法是愚蠢的,但有效的,添加一个button到您的窗体,看起来就像在DTP下拉箭头,使其重叠箭头,所以它被点击,而不是箭头。

一些示例代码让button重叠下拉箭头:

  public Form1() { InitializeComponent(); var btn = new Button(); btn.BackgroundImage = Properties.Resources.DropdownArrow; btn.FlatStyle = FlatStyle.Flat; btn.BackColor = Color.FromKnownColor(KnownColor.Window); btn.Parent = dateTimePicker1; btn.Dock = DockStyle.Right; btn.Click += showMonthCalendar; dateTimePicker1.Resize += delegate { btn.Width = btn.Height = dateTimePicker1.ClientSize.Height; }; } 

Click事件处理程序需要显示一个包含MonthCalendar的对话框:

  private void showMonthCalendar(object sender, EventArgs e) { dateTimePicker1.Focus(); using (var dlg = new CalendarForm()) { dlg.DateSelected += new DateRangeEventHandler((s, ea) => dateTimePicker1.Value = ea.Start); dlg.Location = dateTimePicker1.PointToScreen(new Point(0, dateTimePicker1.Height)); dlg.ShowDialog(this); } } 

使用CalendarForm添加一个无边界的表单,并且只包含一个MonthCalendar:

 public partial class CalendarForm : Form { public event DateRangeEventHandler DateSelected; public CalendarForm() { InitializeComponent(); this.StartPosition = FormStartPosition.Manual; monthCalendar1.Resize += delegate { this.ClientSize = monthCalendar1.Size; }; monthCalendar1.DateSelected += monthCalendar1_DateSelected; } void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e) { if (DateSelected != null) DateSelected(this, e); this.DialogResult = DialogResult.OK; } } 

猜测:
发生该错误的原因是datetimepicker的表面直到发送单击消息后才呈现。

接下来的步骤回答:
如果可用,请尝试使用某些第三方date时间选取器控件进行testing 我意识到这不是一个完整的答案,因为我不知道它是否会解决您的问题。

其他可能的答案:调整任务面板以适应控件。 这将清理错误,但从用户的angular度看起来有点怪异。