如何设置Optional ByRef的默认值? VB.NET 2010

时间:2015-03-22 20:06:10

标签: vb.net arguments optional byref

我有这个代码工作正常。但是我想传递默认参数,以防ByRef没有放入param使用Optional ......请忽略凌乱的评论,因为很多都不正确甚至属于。我将继续评论下一个=]

    Private Function openInBrowse(ByRef bgwargs As bgwargs)
    ' Example I want to do: Optional ByRef bgwargs As bgwargs = ?????

以下是没有代表的整个计划。

Imports System
Imports System.IO
Imports System.Xml
Imports iTextSharp
Imports iTextSharp.text
Imports iTextSharp.text.pdf
Imports iTextSharp.text.xml
Imports System.Security
Imports System.Reflection
Imports System.Data.Odbc
Imports System.Collections.Generic
Imports System.Windows
Imports System.ComponentModel
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms

Public Class Form1

Public Sub New()
    InitializeComponent()
    Dim bgwargs As bgwargs = New bgwargs()
    bgwargs._browserReadyState = Me.PDFWebBrowser.ReadyState
    bgwargs._browserObject = Me.PDFWebBrowser
    bgwargs._progressObject = Me.ProgressBar1
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Try
    MsgBox(ListBox1.SelectedItem.ToString)
Catch ex As Exception

End Try

End Sub

Private Function BlankBrowser(ByRef bgwargs As bgwargs)
    ' Get argument.
    'Dim args As bgwargs = New bgwargs()

    ' bgwargs._browserObject = Browser
    If bgwargs._browserObject.IsDisposed = False Then
        bgwargs._browserObject.Navigate("about:blank")
        '  MsgBox("after navigate")
        While Not bgwargs._browserReadyState <> WebBrowserReadyState.Complete
            ' MsgBox("looping")
            Application.DoEvents()
            System.Threading.Thread.Sleep(100)
            Return 1
        End While
    Else
        '   MsgBox("exiting loop")
        'TODO: Create New PDF WebBrowser
        Return 0
    End If
    ' MsgBox("after end if")
    Return 0
End Function
Private Function openInBrowse(Optional ByRef bgwargs As bgwargs = )
    ' Get argument.
    'Dim args As bgwargs = New bgwargs()
    ' bgwargs._browserObject = Browser
    '  MsgBox("called")
    If bgwargs._browserObject.IsDisposed = False Then
        '    MsgBox("not disposed")
        bgwargs._browserObject.Navigate("file:\\" + bgwargs._TempPDF + "#toolbar=0&navpanes=0")
        '   MsgBox("after navigate")
        While Not bgwargs._browserReadyState <> WebBrowserReadyState.Complete
            '    MsgBox("while looping")
            Application.DoEvents()
            System.Threading.Thread.Sleep(100)
            Return 1
        End While
        '  MsgBox("not in loop")
    Else
        'TODO: Create New PDF WebBrowser
        Return 0
    End If
    Return 0
End Function

Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveButton.Click

    ' Create the argument object.

    Dim bgwargs As bgwargs = New bgwargs()
    Dim location = Assembly.GetExecutingAssembly().Location
    Dim appPath = Path.GetDirectoryName(location)       ' C:\Some\Directory
    Dim TempPDF As String = (appPath + "\tmp\" + ComboTemplates.SelectedItem + ".pdf")
    Dim TemplatePDF As String = (appPath + "\Templates\" + ComboTemplates.SelectedItem + ".pdf")
    Dim NewPDF As String = (appPath + "\Saved Invoices\" + ComboTemplates.SelectedItem + ".pdf")
    Dim ComboSelected As String = ComboTemplates.SelectedItem
    '   args._a = 5
    '   args._b = 6
    ' Start up the BackgroundWorker1.
    ' ... Pass argument object to it.
    bgwargs._browserReadyState = PDFWebBrowser.ReadyState
    bgwargs._browserObject = PDFWebBrowser
    bgwargs._progressObject = ProgressBar1
    bgwargs._TempPDF = TempPDF
    bgwargs._NewPDF = NewPDF
    bgwargs._TemplatePDF = TemplatePDF
    bgwargs._ComboSelectedItem = ComboSelected
    bgwargs._appPath = appPath
    ' MsgBox(NewPDF, TempPDF, TemplatePDF)
    ' Start up the BackgroundWorker1. xmltopdf etc.
    Me.BackgroundWorker1.RunWorkerAsync(bgwargs)
    ' Dim arg As Object = bgwargs._TempPDF(4)

    'Me.BackgroundWorker1_DoWork(arg, ).RunWorkerAsync(bgwargs)

    'MsgBox(PDFWebBrowser.Url.AbsolutePath)



End Sub
'  Private Sub createNode(ByVal fName As String, ByVal lName As String, ByVal writer As XmlTextWriter)
Private Sub createNode(ByVal writer As XmlTextWriter)

    'Global Declarations
    Dim colList As New List(Of String)
    Dim rowList As New List(Of String)
    '   Dim appLocation = Assembly.GetExecutingAssembly().Location
    '  Dim appPath = Path.GetDirectoryName(appLocation)       ' C:\Some\Directory
    ' GetDataTable()
    If Me.DataGridView.Columns.Count > 0 Then

        For i As Integer = 0 To Me.DataGridView.Columns.Count - 1
            '  Dim dataColumn_1 As New DataColumn(DataGridView.Columns(i).HeaderText.ToString(), GetType(String))
            ' dataTable.Columns.Add(dataColumn_1)
            'Now Add some row to newly created dataTable
            ' Dim ivalue As String = i
            ' MsgBox("ivalue: " + ivalue)
            ' MsgBox(Me.DataGridView.Columns(i).HeaderText)

            Console.WriteLine("Simulating PDF Write...")
            Dim colText As String = Me.DataGridView.Columns(i).HeaderText
            Console.WriteLine("Writing Parent...")
            Console.WriteLine(colText)
            writer.WriteStartElement(colText)





            For r As Integer = 0 To Me.DataGridView.Rows.Count - 1
                '  Dim rvalue As String = i
                ' MsgBox("rvalue: " + rvalue)
                '  MsgBox(Me.DataGridView.Rows(r).Cells(i).Value)
                Dim rowText As String = Me.DataGridView.Rows(r).Cells(i).Value
                Console.WriteLine("Writing Child...")
                Console.WriteLine(rowText)
                writer.WriteString(rowText)
                Console.WriteLine("Writing End Element...")
                writer.WriteEndElement()
                rowList.Add(rowText)

                r = r + 1
            Next r
        Next i


    End If


    '  Console.WriteLine("Simulating PDF Write...")
    '   For Each col As String In colList
    '        Console.WriteLine("Writing Parent...")
    'Console.WriteLine(col)
    ' writer.WriteStartElement(col)
    '   For Each row As String In rowList
    'Console.WriteLine("Writing Child...")
    '   Console.WriteLine(row)
    '    writer.WriteString(row)
    ' Next row
    '  writer.WriteEndElement()
    ' Next col
    ''''  writer.WriteStartElement("FirstName")
    '  writer.WriteString(fName)

    '''' '   writer.WriteStartElement("LastName")
    '  writer.WriteString(lName)
    '  writer.WriteEndElement()
End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    'Global Declarations
    Dim colList As New List(Of String)
    Dim rowList As New List(Of String)
    Dim appLocation = Assembly.GetExecutingAssembly().Location
    Dim appPath = Path.GetDirectoryName(appLocation)       ' C:\Some\Directory




    Dim doc As XmlDocument = New XmlDocument()

    'Populate Template Files ComboBox
    ComboTemplates.Items.Clear()
    ComboTemplates.Text = Nothing

    Dim dir As New DirectoryInfo(appPath + "\Templates\")

    '  ComboTemplates.Items.Add(System.IO.Path.GetFileNameWithoutExtension(myItem))

    'get all files in folder with .xml extension
    Dim strFiles() As FileInfo = dir.GetFiles("*.pdf")

    'for each file add to combobox
    For Each pdfItem In strFiles
        'ComboTemplates.Items.Add(pdfItem.ToString)
        ComboTemplates.Items.Add(System.IO.Path.GetFileNameWithoutExtension(pdfItem.ToString))
    Next
    If ComboTemplates.Items.Count > 0 Then
        ComboTemplates.SelectedIndex = 0    ' The first item has index 0 '
    End If
    'Load Selected Template XML in Combo Box

    doc.Load(appPath + "\xml\" + ComboTemplates.SelectedItem + ".xml")
    ListBox1.Items.Clear()
    For Each node As XmlNode In doc.DocumentElement.SelectNodes("*")
        ' MsgBox(node.Name)

        ListBox1.Items.Add(node.Name)
    Next

    Dim ds As New DataSet
    ds.ReadXml(appPath + "\xml\" + ComboTemplates.SelectedItem + ".xml")
    DataGridView.DataSource = ds.Tables(0)

    Dim pdfTempURL As String = appPath + "\Templates\" + "BlankInvoice.pdf#toolbar=0&navpanes=0"
    PDFWebBrowser.Navigate("about:blank")

    Do Until PDFWebBrowser.ReadyState = WebBrowserReadyState.Complete
        Application.DoEvents()
        System.Threading.Thread.Sleep(100)
    Loop

    PDFWebBrowser.Navigate(pdfTempURL)

End Sub


  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


    Dim location = Assembly.GetExecutingAssembly().Location
    Dim appPath = Path.GetDirectoryName(location)       ' C:\Some\Directory
    'Populate Template Files ComboBox
    ComboTemplates.Items.Clear()
    ComboTemplates.Text = Nothing

    Dim dir As New DirectoryInfo(appPath + "\Templates\")

    '  ComboTemplates.Items.Add(System.IO.Path.GetFileNameWithoutExtension(myItem))

    'get all files in folder with .xml extension
    Dim strFiles() As FileInfo = dir.GetFiles("*.pdf")

    'for each file add to combobox
    For Each pdfItem In strFiles
        'ComboTemplates.Items.Add(pdfItem.ToString)
        ComboTemplates.Items.Add(System.IO.Path.GetFileNameWithoutExtension(pdfItem.ToString))
    Next
    If ComboTemplates.Items.Count > 0 Then
        ComboTemplates.SelectedIndex = 0    ' The first item has index 0 '
    End If
    'Load First Template in Combo Box


    Dim doc As New XmlDocument()


    doc.Load(appPath + "\xml\" + ComboTemplates.SelectedItem + ".xml")

    For Each node As XmlNode In doc.DocumentElement.SelectNodes("*")
        ' MsgBox(node.Name)
        ListBox1.Items.Add(node.Name)
    Next

    Dim ds As New DataSet
    ds.ReadXml(appPath + "\xml\" + ComboTemplates.SelectedItem + ".xml")
    Me.DataGridView.DataSource = ds.Tables(0)

    Dim pdfTempURL As String = appPath + "\Templates\" + "BlankInvoice.pdf#toolbar=0&navpanes=0"
    Me.PDFWebBrowser.Navigate(pdfTempURL)
End Sub


' Navigates to the given URL if it is valid. 
Private Sub Navigate(ByVal address As String)

    If String.IsNullOrEmpty(address) Then Return
    If address.Equals("about:blank") Then Return
    If Not address.StartsWith("http://") And _
        Not address.StartsWith("https://") Then
        address = "http://" & address
    End If

    Try
        PDFWebBrowser.Navigate(New Uri(address))
    Catch ex As System.UriFormatException
        Return
    End Try

End Sub
Private Function ShellExecute(ByVal File As String) As Boolean
    Dim myProcess As New Process
    myProcess.StartInfo.FileName = File
    myProcess.StartInfo.UseShellExecute = True
    myProcess.StartInfo.RedirectStandardOutput = False
    myProcess.Start()
    myProcess.Dispose()
    Return True
End Function
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
     ByVal bgwargs As System.ComponentModel.DoWorkEventArgs) _
     Handles BackgroundWorker1.DoWork


    Dim bw As BackgroundWorker = New BackgroundWorker()
    ' Do not access the form's BackgroundWorker reference directly. 
    ' Instead, use the reference provided by the sender parameter. 
    '  Dim bw As BackgroundWorker = New CType(sender, BackgroundWorker)

    ' Extract the argument. 
    Dim arg As bgwargs = bgwargs.Argument

    bgwargs.Result() = {arg._browserObject, arg._browserReadyState, arg._progressObject, arg._TempPDF, arg._NewPDF, arg._TemplatePDF, arg._ComboSelectedItem, arg._appPath}


    SavePDF(bw, arg)

    ' If the operation was canceled by the user,  
    ' set the DoWorkEventArgs.Cancel property to true. 
    If bw.CancellationPending Then
        bgwargs.Cancel = True
    End If
End Sub

' This event handler demonstrates how to interpret  
' the outcome of the asynchronous operation implemented 
' in the DoWork event handler. 
Private Sub backgroundWorker1_RunWorkerCompleted( _
ByVal sender As Object, ByVal bgwargsEvents As RunWorkerCompletedEventArgs) _
Handles BackgroundWorker1.RunWorkerCompleted


    If bgwargsEvents.Cancelled Then
        ' The user canceled the operation.
        MessageBox.Show("Operation was canceled")
    ElseIf (bgwargsEvents.Error IsNot Nothing) Then
        ' There was an error during the operation. 
        Dim msg As String = String.Format("An error occurred: {0}", bgwargsEvents.Error.Message)
        MessageBox.Show(msg)
    Else
        ' The operation completed normally. 
        '  Dim msg As String = String.Format("Result = {0}", bgwargsEvents.Result)
        ' Called when the BackgroundWorker is completed.

        Dim TempPDF As Object = bgwargsEvents.Result(5)

        openInBrowser(bgwargsEvents.Result)

        SetSaveButton(True)


    End If
End Sub


Private Sub SavePDF(ByVal bw As BackgroundWorker, ByRef bgwargs As bgwargs)
    ' Do some time-consuming work on this thread.

    ' Dim bgwargs As bgwargs = New bgwargs()
    ' bgwargs = args
    SetSaveButton(False)
    ' Me.PDFWebBrowser.Hide()
    ' Me.PDFWebBrowser.dis()
    BlankBrowser(bgwargs)
    '  MsgBox(bgwargs._browserReadyState)
    Do Until bgwargs._browserReadyState <> WebBrowserReadyState.Complete
        Application.DoEvents()
        System.Threading.Thread.Sleep(100)
    Loop
    '  MsgBox(bgwargs._browserReadyState)
    Dim colList As New List(Of String)
    Dim rowList As New List(Of String)

    ' Get argument.
    ' Dim args As ArgumentType = New ArgumentType()
    ' args._browserObject = PDFWebBrowser
    'args._progressObject = ProgressBar1
    'DO MORE WORK
    '  Dim pdfTemp As String = appPath + "\Templates\" + "BlankInvoice.pdf" ' ---> It's the original pdf form you want to fill
    ' Dim newFile As String = appPath + "\Saved Invoices\" + "NewInvoice.pdf" ' ---> It will generate new pdf that you have filled from your program

    Dim xmlForm As String = bgwargs._appPath + "\xml\" + bgwargs._ComboSelectedItem + ".xml"
    ' Dim tempPDF As String = bgwargs._TempPDF
    SetProgress_instanceSafe(0, 100)
    Try

        'Write the XML XFA File
        Dim writer As New XmlTextWriter(xmlForm, System.Text.Encoding.UTF8)
        writer.WriteStartDocument(True)
        writer.Formatting = Formatting.Indented
        writer.Indentation = 2
        writer.WriteStartElement("form1")

        ' createNode(tBoxFirstname.Text, tBoxLastname.Text, writer)
        createNode(writer)

        writer.WriteEndDocument()
        writer.Close()


        'Use the XML File and Create the PDF Fillables
        Dim pdfReader As New PdfReader(bgwargs._TemplatePDF)

        Dim pdfStamper As New PdfStamper(pdfReader, New FileStream(
        bgwargs._NewPDF, FileMode.Create))
        Dim D As Integer
        Dim len As Long = pdfReader.EofPos - 1
        '  MsgBox(len)
        '  MsgBox(pdfReader.FileLength)
        '    ProgressBar1.Minimum = 0
        '    ProgressBar1.Maximum = 100

        Do Until len >= bgwargs._NewPDF.Length
            ' MsgBox(newFile.Length)
            D = bgwargs._NewPDF.Length / len * 50
            '  ProgressBar1.Value = D
            SetProgress_instanceSafe(D - 1, 50)
        Loop
        pdfStamper.AcroFields.Xfa.FillXfaForm(xmlForm)
        pdfStamper.FormFlattening = False

        pdfStamper.Close()
        pdfReader.Close()



        '   Try
        BlankBrowser(bgwargs)
        While Not bgwargs._browserReadyState <> WebBrowserReadyState.Complete
            '   MsgBox(e.Result.ToString() + " 4th")
            ' 
            Application.DoEvents()
            System.Threading.Thread.Sleep(100)
        End While

        '  MsgBox("File Open 1?:" + IsFileOpen(bgwargs._NewPDF, bgwargs).ToString())
        '  MsgBox("2? File Open 2?:" + IsFileOpen(bgwargs._TempPDF, bgwargs).ToString())
        Do While (IsFileOpen(bgwargs._NewPDF, bgwargs) = False AndAlso IsFileOpen(bgwargs._TempPDF, bgwargs) = False)

            ' MsgBox("b4 copy")
            Console.WriteLine("Attempting to copy file...")
            BeginCopy(Path.Combine(bgwargs._NewPDF), Path.Combine(bgwargs._TempPDF), bgwargs)
            ' Will overwrite if the destination file already exists.
            ' MsgBox("after copy")

        Loop

        'MsgBox("after copy file while loop")
    Catch ex As IOException
        MsgBox("File write Error!" + Environment.NewLine + bgwargs._NewPDF)
    End Try


    Dim Message As String = "File Saved to: " + Environment.NewLine + bgwargs._NewPDF + Environment.NewLine + Environment.NewLine + "Open the file Now?"
    Dim Caption As String = "Invoice Save Complete"
    Dim Buttons As MessageBoxButtons = MessageBoxButtons.YesNo

    Dim Result As DialogResult

    'Displays the MessageBox

    Result = MessageBox.Show(Message, Caption, Buttons)

    ' Gets the result of the MessageBox display. 

    If Result = System.Windows.Forms.DialogResult.Yes Then
        Console.WriteLine("UserChose Chose YES")
        '  openInBrowser(bgwargs)
        System.Threading.Thread.Sleep(200)
        ShellExecute(bgwargs._NewPDF)
        System.Threading.Thread.Sleep(100)
        SetProgress_instanceSafe(0, 100)
        ReportProgress(bgwargs, BackgroundWorker1)

    Else
        Console.WriteLine("UserChose Chose NO")

        ' openInBrowser(bgwargs)
        ' System.Threading.Thread.Sleep(100)
        SetProgress_instanceSafe(0, 100)
        ReportProgress(bgwargs, BackgroundWorker1)
    End If

    Try




    Catch ex As Exception

        If TypeOf ex Is Exception Then
            Console.WriteLine(ex)
            If PDFWebBrowser.IsDisposed = False Then
                '   MsgBox(e.Result.ToString() + " 3rd")

                While Not bgwargs._browserReadyState <> WebBrowserReadyState.Complete
                    '   MsgBox(e.Result.ToString() + " 4th")
                    ' 
                    Application.DoEvents()
                    System.Threading.Thread.Sleep(100)
                End While


            Else
                'TODO: Create New PDF WebBrowser
            End If
        End If
    End Try




End Sub

' This method demonstrates a pattern for making thread-safe
' calls on a Windows Forms control. 
'
' If the calling thread is different from the thread that
' created the TextBox control, this method creates a
' SetTextCallback and calls itself asynchronously using the
' Invoke method.
'
' If the calling thread is the same as the thread that created
' the TextBox control, the Text property is set directly. 

Private Sub SetText(ByVal [text] As String)

    ' InvokeRequired required compares the thread ID of the
    ' calling thread to the thread ID of the creating thread.
    ' If these threads are different, it returns true.
    If Me.textBox1.InvokeRequired Then
        Dim d As New SetTextCallback(AddressOf SetText)
        Me.Invoke(d, New Object() {[text]})
    Else
        Me.textBox1.Text = [text]
    End If
End Sub

' This method demonstrates a pattern for making thread-safe
' calls on a Windows Forms control. 
'
' If the calling thread is different from the thread that
' created the TextBox control, this method creates a
' SetTextCallback and calls itself asynchronously using the
' Invoke method.
'
' If the calling thread is the same as the thread that created
' the TextBox control, the Text property is set directly. 

Private Sub SetSaveButton(ByVal [enabled] As Boolean)

    ' InvokeRequired required compares the thread ID of the
    ' calling thread to the thread ID of the creating thread.
    ' If these threads are different, it returns true.

    If Me.SaveButton.InvokeRequired Then
        Dim d As New SetSaveButtonCallback(AddressOf SetSaveButton)
        Me.Invoke(d, New Object() {[enabled]})
    Else
        Me.SaveButton.Enabled = [enabled]
    End If
End Sub

Public Function SetProgress_instanceSafe(ByVal paramValue As Integer, ByVal paramMaximum As Integer) As Integer
    If Me.ProgressBar1.InvokeRequired Then
        Me.ProgressBar1.Invoke(New delegate_ProgressUpdate(AddressOf Me.SetProgress_instanceSafe), paramValue, paramMaximum)
    Else
        Me.ProgressBar1.Maximum = paramMaximum
        Me.ProgressBar1.Value = paramValue
        ' Me.ProgressBar1.PerformStep()
        Me.ProgressBar1.Update()
    End If
    Return paramValue
End Function




' This method models an operation that may take a long time  
' to run. It can be cancelled, it can raise an exception, 
' or it can exit normally and return a result. These outcomes 
' are chosen randomly. 
Private Function TimeConsumingOperation( _
ByVal bw As BackgroundWorker, _
ByVal sleepPeriod As Integer) As Integer

    Dim result As Integer = 0

    Dim rand As New Random()

    While Not bw.CancellationPending
        Dim [exit] As Boolean = False

        Select Case rand.Next(3)
            ' Raise an exception. 
            Case 0
                Throw New Exception("An error condition occurred.")
                Exit While

                ' Sleep for the number of milliseconds 
                ' specified by the sleepPeriod parameter. 
            Case 1
                Thread.Sleep(sleepPeriod)
                Exit While

                ' Exit and return normally. 
            Case 2
                result = 23
                [exit] = True
                Exit While

            Case Else
                Exit While
        End Select

        If [exit] Then
            Exit While
        End If
    End While

    Return result
End Function

' <summary> 
' Clean up any resources being used. 
' </summary> 
' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing AndAlso (components IsNot Nothing) Then
        components.Dispose()
    End If
    MyBase.Dispose(disposing)
End Sub 'Dispose

'Private Sub BackgroundWorker1_ProgressChanged() Handles BackgroundWorker1.ProgressChanged
'     SetProgress_instanceSafe(1, 100)

'  End Sub

Function BeginCopy(ByVal Source As String, ByVal Destination As String, ByRef bgwargs As bgwargs)

    '  Dim bgwargs As bgwargs = New bgwargs()

    ' Return value based on the argument.
    ' args._browserObject
    Dim D As Integer
    SetProgress_instanceSafe(50, 100)
    Try

        Dim SourceF As New System.IO.FileStream(Source, System.IO.FileMode.Open)
        Dim DestinationF As New System.IO.FileStream(Destination, System.IO.FileMode.Create)
        Do Until IsFileOpen(Destination, bgwargs) = False
            Dim len As Long = SourceF.Length
            Dim buffer(1024) As Byte
            Dim byteCFead As Integer

            '  bgwargs._progressObject.Minimum = 0



            While DestinationF.Position < len
                D = CInt((DestinationF.Position / len * 100) / 2)
                ' MsgBox(SourceF.Position)
                byteCFead = (SourceF.Read(buffer, 0, 1024))
                DestinationF.Write(buffer, 0, byteCFead)

                ' MsgBox(D)

                '   Me.BackgroundWorker1.ReportProgress(D)

                ' bgwargs._progressObject.Step = D

                ' MsgBox(Progress.Step)
                '     Progress.Value = Progress.Step
                Console.WriteLine(SetProgress_instanceSafe(D, 100).ToString() + " % Before")
                SetProgress_instanceSafe(50 + D, 100)
                If D + D < 100 Then
                    'progReport(D, Me.BackgroundWorker1)
                    SetProgress_instanceSafe(100, 100)
                    '   Progress.PerformStep()
                    'System.Threading.Thread.Sleep(100)
                    '  End If
                End If
                Console.WriteLine("Copying File..." + D.ToString())
                Application.DoEvents()
            End While
            DestinationF.Flush()
            DestinationF.Close()
            SourceF.Close()
            System.Threading.Thread.Sleep(1000)
            SetProgress_instanceSafe(100, 100)
        Loop

        If D + D = 100 Then
            '      bgwargs._progressObject.Value = 0
            ' SetProgress_instanceSafe(100, 100)
            SetSaveButton(True)
            Console.WriteLine("File Copy Success!")

           ' MsgBox(bgwargs._browserReadyState)
            openInBrowser(bgwargs)



        Else
            Console.WriteLine("More than 100 Value Reurned.")
        End If

    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

    Return D
End Function
Public Function IsFileOpen(ByVal file As String, ByRef bgwargs As bgwargs) As Boolean

    ' Get argument.
    'Dim bgwargs As bgwargs = New bgwargs()
    'Dim browser As WebBrowser = bgwargs._browserObject
    Try
        Dim stream As New System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)
        stream.Close()
    Catch ex As Exception

        If TypeOf ex Is System.IO.IOException Then
            ' do something here, either close the file if you have a handle or as a last resort terminate the process - which could cause corruption and lose data
            Console.WriteLine("Sorry. File in use." + Environment.NewLine + (file) + Environment.NewLine + "Retrying...")
            BlankBrowser(bgwargs)
            '          MsgBox(bgwargs._browserReadyState)
            Do Until bgwargs._browserReadyState <> WebBrowserReadyState.Complete
                Application.DoEvents()
                System.Threading.Thread.Sleep(100)
                ' MsgBox((bgwargs._browserReadyState) + "OR" + (bgwargs._browserReadyState))
                '              MsgBox("loop ifo readystate")
            Loop
            Return True
        End If
    End Try
    Return False
End Function
Sub ReportProgress(ByRef bgwargs As bgwargs, ByRef BackgroundWorker1 As BackgroundWorker)
    BackgroundWorker1.ReportProgress(100)
End Sub
End Class

Public Class bgwargs
Public _browserReadyState As Int32
Public _browserObject As WebBrowser
Public _progressObject As ProgressBar
Public _TempPDF As String
Public _NewPDF As String
Public _TemplatePDF As String
Public _ComboSelectedItem As String
Public _appPath As String
End Class

1 个答案:

答案 0 :(得分:0)

Private Function openInBrowse(Optional ByRef bgwargs As SomeClass = Nothing)

可能的用法:

' USAGE #1: A caller who wants to supply a value.
Dim bgwargs1 As SomeClass = ...
openInBrowse(bgwargs1)

' USAGE #2: A caller who has no value to supply, but would like a modified result (if any).
Dim bgwargs2 As SomeClass = Nothing
openInBrowse(bgwargs2)
' ... use "bgwargs2", which may have been changed by `openInBrowse`.

' USAGE #3: A caller who has no value to supply, and doesn't care about the result.
openInBrowse()

拥有这个“可选的ByRef”的好处是,上面的“USAGE#3”不必定义和传入一个不包含任何内容的变量,它不需要。

请注意这种组合(“可选”+“ByRef”)很少使用,而且有些有经验的程序员认为它是“代码味道”。 /> 也就是说,给定一个“ByRef”,总是强制调用者定义并传入一个变量(在这种情况下,包含“Nothing”)是“更安全”的,这样任何未来检查代码的人都会知道什么是完成是 故意

所以,最佳做法,是在没有 ByRef的情况下声明任何Optional

' "bgwargs" is allowed to be "Nothing".
Private Function openInBrowse(ByRef bgwargs As SomeClass)

然后上面的用法#3将无法编译;这样的调用者必须改为使用#2。

为了完整性,请注意在VB中,有一种替代方法,我不推荐,也不涉及“可选”:

Private Function openInBrowse(ByRef bgwargs As SomeClass)

' Usage when you don't have a value to pass in, and don't care about any changes to the ByRef parameter.
openInBrowse(Nothing)

也就是说,将文字传递给ByRef 是合法的。 VB将编译它,就好像您创建了一个临时局部变量并为其赋予了文字值(在本例中为“Nothing”)。
(我不推荐这种替代方案,因为在其他人的代码中遇到它会让人感到困惑;让新程序员不知道这是否是一个意外/错误。特别要注意的是,作为一种“严格”语言的C#没有这样的捷径。恕我直言,这是一件好事,如果你关心的是确信程序是“按照预期”写的。)

有一种情况我可能会使用“Optional ByRef”。一种使用频繁的方法,它在内部创建一个永远不需要暴露的对象。现在一个新调用者可以使用该对象。我不想修改所有现有的调用者,添加新参数。我当然不想“复制/粘贴/修改” - 制作第二个稍微不同的方法版本 - 这是编程中最糟糕的滥用之一。因此,我将以某种方式将此对象返回给那个调用者。 “可选的ByRef ... = Nothing”可能是最简单的解决方案。如果是这样,请执行此操作,注释说明原因

(替代解决方案是重构公共代码.. 99.9%的时间更好的答案是花时间这样做。)