VB.net问题与表格。 [英] VB.net issue with forms.

查看:60
本文介绍了VB.net问题与表格。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会尽力解释我的问题。我不是vb.net的专家,但已经构建了许多应用程序。我目前正在开发一个覆盖预订计划的应用程序。该应用程序以两种形式打开。

第一种形式是永久性表格,保持开放状态,并允许预订代理人向预订程序发出各种命令。

另一种形式运行各种方法来更改底层程序中的预留。当选中第二个表单上的选项时,将运行此代码:

I'll try to explain my issue best I can. I'm not an expert on vb.net but have built a number of applications. I am currently working on an app that overlays a booking program. the app opens with two forms.
The first form is a permanent form that stays open and allows the booking agents to make various commands to the booking program.
The other form runs various methods to change reservations in the underlying program. When an options on the second form is checked then this code is run:

Private Sub frmOWTMain_KeyUp(ByVal sender As Object, ByVal e As
   System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
       If e.KeyCode = Keys.Enter Then
           Me.Hide()
           If Me.cbFare.Checked Then
               Call doFareSavings()
               Me.cbFare.Checked = false
           End If
           Me.Show()
       End If
End Sub





这是被调用的子程序:



This is the called subroutine:

Private Sub doFareSavings()
       Dim myPrice As New Pricing
       If myPrice.checkForFS = False Then '' code that checks for which
                                          '' form to  show
           frmFS.Show()
       ElseIf myPrice.checkForFS = True Then
           frmFSVerify.Show()
       End If
End Sub





我遇到的问题是我想要的frmOWTMain在子例程运行后显示,但在子例程运行时调用其他表单并且Me.show过早运行。

我无法弄清楚如何确保所有子例程(并且有很多)在调用例程运行的Me.show之前运行。这让我抓狂,因为我知道有一个简单的解决方案让我望而却步。我在网上搜索过,但一直无法找到并回答。预先感谢您的帮助



John Murray



The issue I'm having is that I want the frmOWTMain to show after the subroutine is run, but while the subroutine is running it calls other forms and the Me.show runs prematurely.
I can't figure out how to make sure that all the subroutines (and there are quite a few) are run before the Me.show in the calling routine runs. This is driving me crazy because I know there is a simple solution that is eluding me. I've searched all over the web, but have been unable to find and answer. Thanks in advance for any help

John Murray

推荐答案

您可以使用ShowDialog调用表单 - 这个会阻止doFareSavings的执行,直到你关闭表格(以及后面显示的任何其他表格)
You could call the form with ShowDialog - this would block the execution of doFareSavings until you close the form (and any other forms shown later)


我认为这对你有用。它有一个超时值,您可以决定超时时该怎么做。 。

I think this would work for you. It has a timeout value and you can decide what to do if it times out. .
Private Sub doFareSavings()
       Dim myPrice As New Pricing
       If myPrice.checkForFS = False Then ' code that checks for which
                                          ' form to  show
           frmFS.bolCompletedWork = False
           frmFS.Show()

            'InsertedCode
            Dim TimeOutSeconds As Integer = 10
            Dim TimeOutTime As Date = DateAdd(DateInterval.Second, TimeOutSeconds, Now)
            While Now < TimeOutTime
                If frmFS.bolCompletedWork Then
                    'do anything you like here
                    Exit Sub
                End If
            End While
            'Things have timed out so put some fail safe code here
            MsgBox("timeout")


       ElseIf myPrice.checkForFS = True Then
           frmFSVerify.bolCompletedWork = False
           frmFSVerify.Show()

            'InsertedCode
            Dim TimeOutSeconds As Integer = 10
            Dim TimeOutTime As Date = DateAdd(DateInterval.Second, TimeOutSeconds, Now)
            While Now < TimeOutTime
                If frmFSVerify.bolCompletedWork Then
                    'do anything you like here
                    Exit Sub
                End If
            End While
            'Things have timed out so put some fail safe code here
            MsgBox("timeout")


       End If
End Sub



希望这个帮助。


Hope this helps.


我处理这样的事情的方法是将所有doFairSavings()功能放在后台线程上。我不认为我会使调用形式也隐形。相反,我会在其上放置一些进度信息或忙动画。然后,当doFairSavings()完成时,我会使用委托和me.invoke()回调到UI线程,这样我就可以更新我需要的任何表单元素而不必担心跨线程错误。然后我会开始任何需要展示的形式。



我不确定你对这个主题你可能知道什么,所以我要回顾你想做的一切需要知道我要理解的例子(在底部)。



好​​的,有点关于线程。



您应该将它们视为一个单独的程序,只能通过共享内存连接到您的程序。这意味着您声明的公共变量将可供您创建的任何线程访问,但是通过多个线程访问这些变量可能会非常棘手。写入变量的多个线程可能导致这些变量中包含的数据损坏,或者在某些情况下导致数值变量包含您不想要的值,并且没有预料到。因此,当读取或写入来自多个线程的变量时,您应该将这些调用包装在synclock语句中。



当您在vb.net中创建线程时,您可以分配一个Sub或Function居住的线程,如下所示:



The way I would handle something like this would be to put all the doFairSavings() functionality on a background thread. I don't think I would make the calling form invisible either. Instead I would put some progress information, or a "busy" animation on it. Then, when doFairSavings() is complete, I would have it call back into the UI thread using a delegate and me.invoke() so I could update any form elements I needed to without worrying about cross thread errors. Then I would start whatever forms need to be shown.

I'm not sure what you may know about this subject, so I'm going go over everything you will need to know to understand the example I'm going to give (at the bottom).

Ok, a little about threads.

You should think of them as a separate program that is connected to yours only by shared memory. This means that public variables you declare will be accessible to any threads you create, but accessing these variables by multiple threads can be tricky. Multiple threads writing to a variable can cause the data contained in those variables to become corrupt, or in some cases cause numeric variables to contain values you didn't want, and didn't expect. So when reading to or writing to variables from multiple threads, you should wrap those calls in a synclock statement.

When you create a thread in vb.net, you assign the thread a Sub or Function to live in, like this:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim thisNewThread As New Threading.Thread(AddressOf BackgroundThread)
    thisNewThread .Start()

End Sub

Private Sub BackgroundThread()
    ' All code here is running on the new thread!
End Sub





在上面的代码中,单击Button1时将创建一个新线程并开始在Sub BackgroundThread()中运行。线程可以访问该Sub范围内的任何变量 - 这意味着如果BackgroundThread()是您创建的表单,那么它将可以访问任何函数,私有或公共变量以及在该表单中声明的​​对象,或者公共变量和模块中声明的对象。



创建的线程的一条经验法则是它们无法访问表单上的控件。窗体上的控件由UI线程创建,只有UI线程可以读取或写入这些控件。如果您尝试从新线程更改表单文本框的文本,则会(可能)在您的应用程序中抛出一个跨线程违规执行。



我们绕过这可以通过使用DELEGATES,.InvokeRequired()和.Invoke()。



委托是一种保存Sub或函数地址并传递给它的方法一个生活在别处的功能。然后具有委托的方法可以使用它,程序执行返回到保存的函数 - 即使使用委托的代码在另一个类或对象中。



它的工作方式如下:





In the code above, when you click on Button1 a new thread will be created and begin to run in the Sub BackgroundThread(). The thread has access to any variables in that Sub's scope - meaning if BackgroundThread() is in a form you'd created, then it would have access to any functions, private or public variables and objects declared in that form, or public variables and objects declared in your modules.

One rule of thumb for your created threads is that they can not access controls on your form. Controls on your form were created by the UI thread, and only the UI thread can read from or write to those controls. If you try to change the text of your form's textbox from the new thread, a cross thread violation exeption will (probably) be thrown in your application.

We get around this by using DELEGATES, .InvokeRequired() and .Invoke().

A delegate is a way for you to save the address of a Sub or function and pass it to a function that lives elsewhere. Then the method that has the delegate can use it, and program execution returns to the saved function - even if the code that's using the delegate is within another class or object.

It works like this:

Public Class Form1

    Private Delegate Sub OurPrototype(ByVal message As String)
    Private theCallback As OurPrototype

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        'Dim t As New Threading.Thread(AddressOf BackgroundThread)
        't.Start()

        theCallback = AddressOf Callback
        theCallback("hello")
    End Sub

    'Private Sub BackgroundThread()

    'End Sub

    Private Sub Callback(ByVal message As String)
        MsgBox(message)
    End Sub
End Class





这是新项目中新表格的所有代码。在顶部,我们创建了一个委托原型。它是将使用此原型创建的委托中包含的子或函数的签名或格式。您将看到它与我们在按钮单击事件中分配给我们的委托的Sub匹配。如果你点击按钮,会弹出一个包含文本hello的消息框。



我知道它现在看起来不是很有用,但是您可以将该委托作为参数传递给您从其中一个类创建的对象,并且当从该类的深度调用委托时,程序执行将返回到该函数,并且您将看到消息框包含文本hello。



你也可以使用它来改变线程使用.Invoke() - 这就是神奇的地方。



大多数控件和所有表单都包含.Invoke()和.InvokeRequired()函数。 .InvokeRequired()返回一个布尔值,表示你当前的线程是不是天气是UI线程。如果不是,并且您需要在UI线程上,则使用.Invoke(),如下所示:





This is all the code from a new form in a new project. At the top, we've created a delegate prototype. It's the signature, or format of the sub or function that will be contained in delegates created using this prototype. You'll see that it matches the Sub that we assigned to our delegate in the button click event. If you were to click the button, a message box would pop up containing the text "hello".

I know it doesn't seem very useful right now, but you could pass that delegate as a parameter to an object you've created from one of your classes, and when the delegate is called from the depths of that class, program execution would return to that function, and you'd see the message box containing the text "hello".

You can also use it to change threads using .Invoke() - and that's really where the magic is.

Most controls and all forms contain the .Invoke() and .InvokeRequired() functions. .InvokeRequired() returns a boolean value indicating weather or not your current thread is the UI thread. If it's not, and you need to be on the UI thread, you use .Invoke(), like this:

Private Sub Callback(ByVal message As String)

    If Me.InvokeRequired Then
        Me.Invoke(theCallback, message)
    Else
        Me.Text = message
    End If

End Sub





这是我们的回调函数再次,只有这一次,如果它被我们的新线程调用,me.InvokeRequired()将为True。如果是这种情况,那么回调子将运行AGAIN,但这次它将在UI线程上运行。第二次,.InvokeRequired()将为False,并且该if语句的else部分中的代码将运行 - 将表单上的文本设置为消息字符串中的任何内容(在我们的示例中,它将是hello) 。



好​​的,这是您应该了解的示例代码的背景知识......这里是:





Here's our callback function again, only this time if it's called by our new thread, me.InvokeRequired() will be True. If that's the case, then the callback sub will be run AGAIN, but this time it will be on the UI thread. The second time through, .InvokeRequired() will be False, and the code in the else portion of that if statement will run - setting the text on your form to whatever's in the message string (in our case it will be "hello").

Ok, that's the background stuff you should know to understand this example code... Here it is:

 Private Delegate Sub OurPrototype(ByVal message As String)
 Private theCallback As OurPrototype

 Private Sub frmOWTMain_KeyUp(ByVal sender As Object, ByVal e As
    System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If e.KeyCode = Keys.Enter Then
            Me.Hide()
            If Me.cbFare.Checked Then
                theCallback = AddressOf Callback

                Dim bgThread as New Thread(AddressOf ourThread)
                bgThread.Start()

                'Call doFareSavings()
                'Me.cbFare.Checked = false
            End If
            'Me.Show()
        End If
 End Sub

Private Sub ourThread()
    ' Do your doFareSavings() work here. When your done, call your delegate:
    theCallback("you can incluse information in this string about what form to show here")
End Sub

 Private Sub Callback(ByVal message As String)

     If Me.InvokeRequired Then
         Me.Invoke(theCallback, message)
     Else
         ' Show whatever form you like here, directed by the message string
         Me.cbFare.Checked = false
         If message = "whateverForm" Then whateverForm.show()
         Me.Show()
     End If
        
 End Sub





这样做,你的表格在完成所有工作后才会显示。



顺便说一下 - 我希望你意识到这一点没有关于线程和代表的所有信息。这只是基础知识。如果您想了解更多信息,请尝试使用Google或MSDN。关于两者的内容还有很多。



-Pete



Doing it like this, your form will not show until all the work is done.

By the way - I hope you realize that this is nowhere NEAR all the information on threading and delegates. It's just the basics. If you want to know more, try Google or MSDN. There's a lot more to know about both.

-Pete


这篇关于VB.net问题与表格。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆