Делегировать внутри делегата в VB.NET - PullRequest
1 голос
/ 23 марта 2010

Я пытаюсь написать VB.NET-альтернативу анонимной функции C #.

Я хочу вызвать Threading.SynchronizationContext.Current.Send, который ожидает, что делегат типа Threading.SendOrPostCallback будет передан ей.,Фон здесь , но поскольку я хочу передать строку в MessageBox.Show, а также перехватить DialogResult, мне нужно определить другой делегат внутри.Я борюсь с синтаксисом VB.NET, как из традиционного стиля делегата, так и из лямбда-функций.

Ниже я расскажу о традиционном синтаксисе, но у меня есть ощущение, что это должно быть намного проще, чем это:

Private Sub CollectMesssageBoxResultFromUserAsDelegate(ByVal messageToShow As String, ByRef wasCanceled As Boolean)
    wasCanceled = False
    If Windows.Forms.MessageBox.Show(String.Format("{0}{1}Please press [OK] to ignore this error and continue, or [Cancel] to stop here.", messageToShow), "Continue", Windows.Forms.MessageBoxButtons.OKCancel, Windows.Forms.MessageBoxIcon.Exclamation) = Windows.Forms.DialogResult.Cancel Then
        wasCanceled = True
    End If
End Sub


Private Delegate Sub ShowMessageBox(ByVal messageToShow As String, ByRef canceled As Boolean)


Private Sub AskUserWhetherToCancel(ByVal message As String, ByVal args As CancelEventArgs)

    If args Is Nothing Then args = New System.ComponentModel.CancelEventArgs With {.Cancel = False}

    Dim wasCancelClicked As Boolean
    Dim firstDelegate As New ShowMessageBox(AddressOf CollectMesssageBoxResultFromUserAsDelegate)
    '…. Now what??
    'I can’t declare SendOrPostCallback as below: 
    'Dim myDelegate As New Threading.SendOrPostCallback(AddressOf firstDelegate) 


End Sub

Ответы [ 2 ]

4 голосов
/ 23 марта 2010

Я думаю, что самый простой способ справиться с этим - создать новый объект, который оборачивает отображение окна сообщения. Этот объект затем может быть использован для получения результата.

Например:

Public Class Helper 
  Public WasCanceled as Boolean
  Public Message As String
  Public Done as New ManualResetEvent(false)
  Public Sub New(message as String) 
    Me.Message = message
  End Sub 
  Public Sub ShowMessageBox(unused as Object) 
    If MessageBox.Show(Message) = DialogResult.Cancel Then 
      WasCanceled = True
    Done.Set()
  End Sub 
End Class

Public Sub AskUserWhetherToCancel(context as SynchronizationContext, message As String)
  Dim helper As New Helper(message)
  context.Post(AddressOf helper.ShowMessageBox, Nothing)

  ' Wait for it to finish
  helper.WaitOne()

  if helper.WasCanceled Then 
    ...
  Else
    ...
  End IF
End Sub
1 голос
/ 23 марта 2010

Попробуйте это:

Dim myDelegate As New Threading.SendOrPostCallback(Function(c) firstDelegate) 

Не уверен, что он будет работать именно так, как вам нравится, но он скомпилируется.

Возможно, это то, что вы ищете: Передача параметров делегатам в VB.NET

...