c# - 除非调用 .Show(),否则表单不起作用

标签 c# forms show visible

我有一个表示 USB 设备终端的表单,它一直给我一些错误。在调试了半天没有已知来源的奇怪错误后,我以某种方式发现终端在实例化但未显示时不起作用。当我更改代码并添加 usbTerminal.Show(); 时,它会正常工作。

USBTerminal usbTouchTerminal;

public MainForm()
{

InitializeComponent();

USBSettings usbTouchSettings = new USBSettings();
usbTouchTerminal = new USBTerminal(usbTouchSettings);           //Create Terminal with settings
usbTouchTerminal.StartUSB();                                    
usbTouchTerminal.Show();            //works ONLY when show is here

}

这怎么可能,为什么?我进行了大量搜索,但我的代码都不依赖于终端或主窗体上的 .Visible 属性?

我完全不明白为什么有些表格如果不显示就不能工作。 MSDN 或谷歌也不是真正的帮助。我确信它在实例化但未显示时会正常运行。

附言。我加了

usbTerminal.Show();
usbTerminal.Hide();

并且终端运行正常。

感谢您的帮助!

编辑:

我还应注意,此 usbTerminal 使用 WndProc 覆盖。我不是这方面的专家,但我觉得这可能与此有关。

我应该注意到这是 LibUSBdotnet

    public class USBSettings
{
    /// <summary>
    /// This is the Vender ID Number. (0x0B6A)
    /// </summary>
    public ushort VID { get; set; }

    /// <summary>
    /// This is the Product ID Number. (0x5346)
    /// </summary>
    public ushort PID { get; set; }

    /// <summary>
    /// This is the optional Serial Name. ("")
    /// </summary>
    public string SerialName { get; set; }

    /// <summary>
    /// This is the Reader USB Endpoint. (ReadEndpointID.Ep02)
    /// </summary>
    public ReadEndpointID ReaderEndpoint { get; set; }

    /// <summary>
    /// This is the Writer USB Endpoint. (WriteEndpointID.Ep01)
    /// </summary>
    public WriteEndpointID WriterEndpoint { get; set; }

    /// <summary>
    /// This is the Registry Key for USB settings. ("SOFTWARE\\DEFAULT\\USBPROPERTIES")
    /// </summary>
    public string SubKey { get; set; }

    /// <summary>
    /// This is the default read buffer size for the USB Device.
    /// </summary>
    public int ReadBufferSize { get; set; }

    /// <summary>
    /// This constructor houses default values for all properties.
    /// </summary>
    public USBSettings()
    {
        VID = 0x0B6A;
        PID = 0x5346;
        SerialName = "";
        ReaderEndpoint = ReadEndpointID.Ep02;
        WriterEndpoint = WriteEndpointID.Ep01;
        SubKey = "SOFTWARE\\DEFAULT\\USBPROPERTIES";
        ReadBufferSize = 100;
    }

}

最佳答案

这个问题没有很好的记录,但这对于与设备一起工作的代码来说是相当正常的。他们往往需要了解即插即用事件,这需要创建一个顶层窗口来接收 WM_DEVICECHANGE 通知消息。创建一个 .NET Form 对象是不够的,您还必须为其创建 native 窗口。以典型的 .NET 惰性方式,它发生在最后可能的时刻,当您强制窗口可见时。通过调用 Show() 方法或将 Visible 属性设置为 true。获取即插即用通知的窗口实际上不必可见。

可以创建窗口而不使其可见。这需要修改 USBTerminal 类。粘贴此代码:

    protected override void SetVisibleCore(bool value) {
        if (!this.IsHandleCreated) {
            this.CreateHandle();
            value = false;
        }
        base.SetVisibleCore(value);
    }

然后正常调用 Show() 方法。请注意,在窗口实际变为可见之前,Load 事件不会触发,因此如有必要,请将事件处理程序中的任何代码移至此方法。如果这不是应用程序的主窗口,换句话说不是在您的 Main() 方法中传递给 Application.Run() 的窗口,那么您只需调用 this.CreateHandle() 作为表单构造函数。在这种情况下,不再需要调用 Show()。

关于c# - 除非调用 .Show(),否则表单不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17198386/

相关文章:

javascript - 为什么 form.reset() 在重置处理程序中不起作用?

c# - 应用程序的新实例

c# - 在 VS 2010 中为测试项目设置 useLegacyV2RuntimeActivationPolicy

javascript - 如何将信息输入到一系列表格中并显示该信息?

forms - Perl舞者: Instant response in post

javascript - 通过选择显示下一个字段集

Javascript onClick ShowHide 控制我的整个标题

css - 实时网站上的显示图标字体不正确

c# Azure无法设置blob层

c# - 'generic' 电话号码的基本正则表达式