Как мне сохранить переменную ByRef в диалоговой форме .net winforms? - PullRequest
3 голосов
/ 29 сентября 2008

Я создаю форму «выбора отдела», которая будет служить модальной всплывающей формой со многими из моих «основных» форм приложения Winforms. В идеале пользователь собирается щелкнуть значок рядом с текстовым полем, которое откроет форму, он выберет необходимый отдел, и когда он нажмет OK, диалоговое окно закроется, и я выберу значение, которое я выберу обновить текстовое поле с помощью.

Я уже прошел маршрут, передав владельца диалогового окна в диалоговую форму и выполнив соответствующее событие нажатия кнопки ОК, чтобы выполнить соответствующее обновление, но это вынуждает меня выполнить DirectCast для типа формы, и тогда я могу использовать повторно только в текущей форме.

Мне удалось использовать переменную ByRef в конструкторе и успешно обновить значение, но оно работает только в конструкторе. Если я пытаюсь присвоить значение ByRef какой-либо внутренней переменной в классе Подборщика отдела, я теряю его ссылочный аспект. Это мой основной код, прикрепленный к моей форме:

Public Class DeptPicker

   Private m_TargetResult As String

   Public Sub New(ByRef TargetResult As String)

      InitializeComponent()

      ' This works just fine, my "parent" form has the reference value properly updated.
      TargetResult = "Booyah!"

      ' Once I leave the constructor, m_TargetResult is a simple string value that won't update the parent
      m_TargetResult = TargetResult

   End Sub

   Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click

      DialogResult = Windows.Forms.DialogResult.OK

      ' I get no love here. m_TargetResult is just a string and doesn't push the value back to the referenced variable I want.
      m_TargetResult = "That department I selected."
      Me.Close()

   End Sub

   Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

      DialogResult = Windows.Forms.DialogResult.Cancel
      Me.Close()

   End Sub

End Class

Может кто-нибудь сказать мне, что мне здесь не хватает, или другой подход, чтобы это произошло?

Примечание. Образец кода есть в VB.NET, но я также отвечу на любые вопросы C #. 8 ^ D

Ответы [ 5 ]

4 голосов
/ 29 сентября 2008

В таких случаях я обычно либо

  • Напишите функцию ShowDialog, которая делает то, что я хочу (например, возвращает значение) или
  • Просто позвольте результату быть свойством в диалоге. Вот как обычные файловые диалоги делают это в BCL. Затем вызывающая сторона должна прочитать свойство, чтобы получить результат. Это нормально, по моему мнению.

Вы также можете объединить эти методы, сделав значение результата свойством в диалоговом окне и создав метод ShowDialog, который возвращает значение этого свойства в виде ByRef, как вы хотите, или в качестве возвращаемого значения, в зависимости от ваших потребностей. *

Я добавлю это как инструкцию по использованию, например (извините, здесь нет VB, и вы сказали, что C # приветствуется):

using (var dlg = new DeptPicker()) {
    if (dlg.ShowDialog() == DialogResult.OK) {
        myTextBoxOrWhatEver.Text = dlg.TargetResult;
    }
}

В самом диалоге просто сделайте это:

void okButton_Click(object sender, EventArgs e)
{
    TargetResult = whatever; // can also do this when the selection changes
    DialogResult = DialogResult.OK;
    Close();
}

Я не использовал новую реализацию ShowDialog в этом примере.

0 голосов
/ 30 сентября 2008

Это может работать:

    // This code in your dialog form.  Hide the base showdialog method 
    // and implement your own versions
    public new string ShowDialog() {
        return this.ShowDialog(null);
    }

    public new string ShowDialog(IWin32Window owner) {
        // Call the base implementation of show dialog
        base.ShowDialog(owner);

        // You get here after the close button is clicked and the form is hidden.  Capture the data you want.
        string s = this.someControl.Text;

        // Now really close the form and return the value
        this.Close();
        return s;
    }

    // On close, just hide.  Close in the show dialog method
    private void closeButton_Click(object sender, EventArgs e) {
        this.Hide();
    }

    // This code in your calling form
    MyCustomForm f = new MyCustomForm();
    string myAnswer = f.ShowDialog();
0 голосов
/ 30 сентября 2008

Public Class DeptPicker

    dim dlgResult as DialogResult

    Public Function GetSelectedDepartment() As String
        Me.Show vbModal
        If (dlgResult = Windows.Forms.DialogResult.OK) Then
            return "selected department string here"
        Else
            return "sorry, you didnt canceled on the form"
        End If
    End Function

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        dlgResult = Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        dlgResult = Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub
End Class

Примечание: я не проверял это. Я надеюсь, вы поняли, что я имею в виду.

OregonGhost: это выглядит лучше?

Пользователь может вызвать новый DeptPicker (). GetSelectedDepartment (). Я не знал, что мне не нужно публиковать ответ снова и мог использовать тот же пост.

Спасибо OregonGhost. Теперь это выглядит нормально?

0 голосов
/ 29 сентября 2008

Вы можете передать ссылку на текстовое поле в модальную форму.

Позвольте пользователю выбрать любой отдел. Когда пользователь нажимает кнопку ОК, присвойте текстовому свойству текстового поля для ссылки текст выбранного идентификатора или идентификатор (зависит от того, что вам нужно)

Я использую код, предоставленный вами.


Public Class DeptPicker

   Private m_TargetTextBox As TextBox

   Public Sub New(ByRef TargetTextBox As TextBox)
      InitializeComponent()

      m_TargetTextBox = TargetTextBox

   End Sub

   Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click

      DialogResult = Windows.Forms.DialogResult.OK

      ' I get no love here. m_TargetResult is just a string and doesn't push the value back to the referenced variable I want.
      m_TargetTextBox.Text = "That department I selected."
      Me.Close()

   End Sub

   Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

      DialogResult = Windows.Forms.DialogResult.Cancel
      Me.Close()

   End Sub

End Class

0 голосов
/ 29 сентября 2008

Проблема в том, что при назначении TargetResult в конструкторе используется строка в качестве ссылки. Строка m_TargetResult является просто копией строки ref, а не ссылкой на исходную строку.

Что касается того, как сделать «указатель» на оригинал, я не знаю.

Это усложняется еще и тем, что VB.NET не поддерживает небезопасные блоки кода, поэтому вы не можете сделать указатель на ссылку на строку.

...