【问题标题】:UITypeEditor is not closing properlyUITypeEditor 没有正确关闭
【发布时间】:2015-07-13 11:53:31
【问题描述】:

我正在使用带有 UITypeEditor 的 UserControl。用户控件有 OK 和 Cancel 按钮,除了显示带有 OK 或 Cancel 的 MessageBox,然后隐藏用户控件外,它们什么都不做。但是,当我单击其中一个按钮时,PropertyGrid 会在 UserControl 所在的位置显示一个空框,直到我单击离开为止。然后该框消失并显示对话框。

这是用户控制代码:

using System;
using System.Windows.Forms;

namespace j2associates.Tools.Winforms.Controls.DesignTimeSupport.SupportingClasses
{
    public partial class SimpleTest : UserControl
    {
        public bool Cancelled { get; set; }

        public SimpleTest()
        {
            InitializeComponent();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            Cancelled = false;
            this.Hide();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Cancelled = true;
            this.Hide();
        }
    }
}

这是 UITypeEditor 代码:

using System;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

using j2associates.Tools.Winforms.Controls.DesignTimeSupport.SupportingClasses;

namespace j2associates.Tools.Winforms.Controls.DesignTimeSupport.Editors
{
    internal class TimeElementsEditor : UITypeEditor // PropertyEditorBase<TimeElementsUserControl>
    {
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }

        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (value.GetType() == typeof(j2aTimePicker.TimeElementOptions))
            {
                var editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
                if (editorService != null)
                {
                    using (var st = new SimpleTest())
                    {
                        editorService.DropDownControl(st);
                        if (st.Cancelled)
                        {
                            MessageBox.Show("Cancel");
                        }
                        else
                        {
                            MessageBox.Show("OK");
                        }
                        editorService.CloseDropDown();
                    }
                }
            }

            return value;
        }
    }
}

任何想法和/或建议将不胜感激。

【问题讨论】:

  • 我没有尝试过,但这种方法存在一个重大缺陷。您不能将焦点从下拉列表中移开。 PropertyGrid 使用鼠标捕获来检测下拉菜单何时需要再次上卷。使用 MessageBox.Show() 取消鼠标捕获。例如,当您对某个值不满意时,可以使用 ErrorProvider 或 Label 来提供诊断或引发异常。或者使用 UITypeEditorEditStyle.Modal
  • 您可能不应该从控件本身控制隐藏或关闭。而是从容器中进行。
  • Hans,给出的示例是一组非常简化的代码来演示问题。 MessageBox 代码在编辑器代码中,而不是在 UserControl 中,因此在 UserControl 关闭之前它不会执行。因此,焦点不会从下拉列表中移开。
  • leppie,隐藏 UserControl 是首先导致我的问题的原因,可能永远不应该这样做。将 EditorService 传递给 UserControl 以便在处理完成时调用它的 CloseDropdown 方法是 UITypeEditor 遍历代码中使用的技术。
  • leppie,你有一些从容器中关闭它的示例代码吗?我同意这将是最好的解决方案。

标签: c# winforms uitypeeditor


【解决方案1】:

唉,找到它总是很容易的。

我需要通过重载的构造函数传入 IWindowsFormsEditorService,对其进行缓存,然后在 Button Click 事件中调用它的 CloseDropdown 方法,而不是隐藏用户控件。它现在按预期工作。

/// <summary>
/// Displays an OK and Cancel button. When one is pressed, 
/// the dialog is closed and a message box is displayed.
/// The actual value of the property is unchanged throughout.
/// </summary>
/// <remarks>The ToolboxItem attribute prevents the control from being displayed in the ToolKit.</remarks>
[ToolboxItem(false)]
public partial class SimpleTest : UserControl
{
    public bool Cancelled { get; set; }

    private IWindowsFormsEditorService m_EditorService;

    // Require the use of the desired overloaded constructor.
    private SimpleTest()
    {
        InitializeComponent();
    }

    internal SimpleTest(IWindowsFormsEditorService editorService)
        : this()
    {
        // Cache the editor service.
        m_EditorService = editorService;
    }

    private void btnOK_Click(object sender, EventArgs e)
    {
        Cancelled = false;
        m_EditorService.CloseDropDown();
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        Cancelled = true;
        m_EditorService.CloseDropDown();
    }
}

这是修改后的编辑器调用:

using (var simpleTest = new SimpleTest(editorService))
{
    editorService.DropDownControl(simpleTest);
    MessageBox.Show(simpleTest.Cancelled ? "Cancelled" : "OK");
}

【讨论】:

    猜你喜欢
    • 2014-03-03
    • 1970-01-01
    • 2017-02-13
    • 2012-10-30
    • 2020-05-21
    • 2019-05-09
    • 1970-01-01
    • 2012-09-25
    • 2018-08-09
    相关资源
    最近更新 更多