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

时间:2013-06-19 18:13:43

标签: 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或谷歌也不是真正的帮助。我确信它在实例化时会正常运行但不会显示。

PS。我添加了

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;
    }

}

4 个答案:

答案 0 :(得分:5)

问题记录很少,但对于与设备一起使用的代码,这是很正常的。他们往往需要了解Plug&amp; amp;播放事件,并且需要创建接收WM_DEVICECHANGE通知消息的顶级窗口。创建.NET Form对象是不够的,您还必须为它创建本机窗口。在典型的.NET懒惰方式中,当您强制窗口可见时,它会在最后一刻发生。通过调用Show()方法或将Visible属性设置为true。实际上并不需要窗口才能获得Plug&amp;播放通知。

可以创建窗口而不会让它可见。这需要修改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()。

答案 1 :(得分:1)

我怀疑这是因为在调用Show()之前未创建基础窗口。由于未创建窗口,因此不会调用自定义WndProc。

要验证,您可以通过查看Handle property来创建窗口而不显示它。正如文档所说 - 如果在您调用时尚未创建句柄,则会创建该句柄。尝试一下,我打赌它会像你Show然后Hide那样工作。

答案 2 :(得分:1)

很难从您所掌握的信息中判断出来,但我认为您正在使用应该使用类的表单。您应该重新考虑您的程序结构,并将其重新编写为一个类,以根据需要保存和传输数据。正如其他一些人所指出的那样,在显示表单并执行方法之前,列表框和/或其他功能都没有运行。

答案 3 :(得分:0)

因为在调用Form onShow事件时会调用一些必需的函数。