문제

나는 "기본"양식의 Winforms 응용 프로그램의 많은 "기본"양식으로 작용할 "부서 선택기"양식을 만들고 있습니다. 이상적으로 사용자는 양식을 팝업하는 텍스트 상자 옆에 아이콘을 클릭하고 필요한 부서를 선택하고 확인을 클릭하면 대화 상자가 닫히고 선택한 값이 있습니다. 텍스트 상자를 업데이트하십시오.

대화 상자의 소유자를 대화 상자의 소유자를 대화 상자 양식으로 전달하고 OK 버튼 클릭 이벤트가 올바른 업데이트를 수행하면서 이미 경로를 수행했지만 양식 유형으로 직접 캐스트를 수행해야합니다. 현재 형태의 피커.

생성자에서 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

도움이 되었습니까?

해결책

그러한 경우, 나는 보통 어느 쪽이든

  • 내가 원하는 것을 수행하는 ShowDialog 함수 (예 : 값을 반환) 또는
  • 결과가 대화 상자의 속성이되도록하십시오. 이것은 공통 파일 대화 상자가 BCL에서 수행하는 방식입니다. 그런 다음 발신자는 결과를 얻으려면 속성을 읽어야합니다. 제 생각에는 괜찮습니다.

또한 결과 값을 대화 상자의 속성으로 만들고 필요에 따라 BYREF 또는 RETURN 값으로 해당 속성 값을 반환하는 ShowDialog 메소드를 작성하여 이러한 방법을 결합 할 수 있습니다.

예를 들어 이것을 사용 지침으로 추가하겠습니다 (예 : 죄송합니다. 여기에 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 구현을 사용하지 않았습니다.

다른 팁

문제는 생성자에 TargetResult를 할당하는 것이 문자열을 참조로 사용한다는 것입니다. m_targetresult 문자열은 원래 문자열에 대한 참조가 아니라 Ref 문자열의 사본 일뿐입니다.

원본에 "포인터"를 만드는 방법에 관해서는 모르겠습니다.

VB.NET은 안전하지 않은 코드 블록을 지원하지 않으므로 문자열을 참조 할 수 없다는 사실에 의해 더욱 어려워집니다.

텍스트 상자 참조를 모달 양식에 전달할 수 있습니다.

사용자가 부서를 선택하게하십시오. 사용자가 확인을 클릭하면 참조 된 텍스트 상자의 텍스트 속성을 선택한 부서의 텍스트 또는 ID로 설정하십시오 (필요한 것에 따라 다름)

귀하가 제공 한 코드를 사용하고 있습니다.


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


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 : 이것이 더 좋아 보입니까?

사용자는 new deptpicker ()를 호출 할 수 있습니다. getSelectedDepartment (). 답을 다시 게시 할 필요가 없으며 같은 게시물을 사용할 수 있다는 것을 몰랐습니다.

감사합니다 Oregonghost. 자, 괜찮아 보입니까?

이것은 작동 할 수 있습니다 :

    // 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();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top