ShowDialog Form property is empty - wpf

I have two of the simplest forms, with a couple of Buttons and a TextBox. I click to open the second form (frmModal) using ShowDialog(), type some text into txtGreeting and press the Yes button. What should happen is that a MessageBox appears confirming the text that was entered into txtGreeting, but it is empty.
I understand that the Form's properties should be accessible until the form goes out of scope, but they disappear straight-away. I can't even read dialog.txtGreeting.Text.
Am I missing anything obvious please?
Public Class frmMain
Private Sub btnModal_Click(sender As Object, e As EventArgs) Handles btnModal.Click
Dim dialog As frmModal
dialog = New frmModal()
Dim result As DialogResult = frmModal.ShowDialog(Me)
If result = Windows.Forms.DialogResult.Yes Then
MessageBox.Show(dialog.Greeting)
End If
'dialog.Dispose()
End Sub
End Class
Public Class frmModal
Public Property Greeting As String
Get
Return txtGreeting.Text
End Get
Set(value As String)
End Set
End Property
Private Sub btnYes_Click(sender As Object, e As EventArgs) Handles btnYes.Click
MessageBox.Show(Greeting)
End Sub
End Class
The Yes button has it's DialogResult property set to Yes.
I've tried moving the dialog-declaration out of the click-event, using an (unnecessary) Dispose(), deliberately assigning the Greeting property in the Yes-click event..

You're effectively instantiating the form twice. By showing frmModal with ShowDialog and then asking for the Greeting value on the instance you created, named 'dialog'.
This should fix it.
Private Sub ModalTestButton_Click(sender As System.Object, e As System.EventArgs) Handles ModalTestButton.Click
Dim dialog As frmModal
dialog = New frmModal()
Dim result As DialogResult = dialog.ShowDialog(Me)
If result = Windows.Forms.DialogResult.Yes Then
MessageBox.Show(dialog.Greeting)
End If
End Sub

Related

Winform dialog show modal form wait for Dialogresult

I need to use "Show()" method for dialog winform using Ironpython
and i need to get result of button pressing and use it in another part of program
how can i wait for pressing OK in modal "Show()" dialog?
mform = Form3()
mform.Show()
# How to wait for button OK
Thx
Use ShowDialog() instead of Show().
Then check "if (mform.DialogResult == DialogResult.OK)"
Suppose you have a main form called Form1 and a secondary form called AddForm which presents some result when the [OK] button is pressed.
The main form then can subscribe to the FormClosed event of the secondary form and pull the result if the user clicked on the [OK] button.
This can all happen in the subroutine where the secondary form is shown
Private Sub Button1.Click(sender as Object, e as EventArgs) Handles Button1.Click
Dim dlg as New AddForm
AddHandler dlg.FormClosed, _
Sub(e,ev) TextBox1.Text = If(dlg.DialogResult = DialogResult.OK, dlg.Result, String.Empty)
dlg.Show()
End Sub
And in the secondary form make sure there is a property called Result which contains the results
The [OK] button has a handler like so
Private Sub Button1_Click(sender as Object, e as EventArgs) Handles Button1.Click
Result = ...
DialogResult = DialogResult.OK
Me.Close()
End Sub
and the [Cancel] button has a handler as so
Private Sub Button2_Click(sender as Object, e as EventArgs) Handles Button2.Click
DialogResult = DialogResult.Cancel
Me.Close()
End Sub

What is the best way to update the source of a XamDataGrid from a different form?

I have a XamDataGrid in my MainWindow which has a Public Shared List(Of Artikelstammdaten) as DataSource. After opening a few other forms I want to add more data to the XamDataGrid with a button click. I thought the easiest way would be just to update the DataSource, but I get an Error:
The reference to an unreleased member requires an object reference.
This is what I have tried:
Private Sub Add_Click(sender As Object, e As RoutedEventArgs)
Dim update = MainWindow.listArtikelstammdaten.Concat(CType(Import.ComparedAccessData, IEnumerable(Of Artikelstammdaten)))
dgArticleMasterData.DataSource = update
Me.Close()
End Sub
If dgArticleMasterData is defined in the MainWindow class, you need to get a reference to the MainWindow instance to be able to access it.
You should be able to find it in the Application.Current.Windows collection:
Private Sub Add_Click(sender As Object, e As RoutedEventArgs)
Dim update = MainWindow.listArtikelstammdaten.Concat(CType(Import.ComparedAccessData, IEnumerable(Of Artikelstammdaten)))
Dim window = Application.Current.Windows.OfType(Of MainWindow).FirstOrDefault()
If window IsNot Nothing Then
window.dgArticleMasterData.DataSource = update
End If
Me.Close()
End Sub

Visual Basic Saving Form info on hide

Im using Visual Basic 2008
I have 2 forms
Main, EditCustomerInfo
Main form contains the following
Public Class Main
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
EditCustomerInfo.ShowDialog()
End Sub
EditCustomerInfo contains a text box and the following
Public Class EditCustomerInfo
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Not CustomerIDTextBox.Text = "" Then
Me.Close()
Else : Me.Hide()
End If
End Sub
WHAT IT DOES:
So with this code alone when i debug the program it takes me to the main form and allows me to click a button to open the editcustomerinfo form
When im on the editcustomerinfo form i have a textbox and a button. If something is typed in the textbox and the button is clicked then the form hides, if nothing is typed in the textbox when the button is clicked then the form closes.
WHAT I WOULD LIKE IT TO DO:
If something is typed in the textbox i would like the button on the editcustomerinfoform to hide the editcustomerinfoform and also create a button on main form that allows the user to bring the editcustomerinfo form back up with what was typed in the text box.
Suggestions?
Automatic behavior, such as this, always worries me. How do you know when a user has completed their input without a lost focus event. If there are no other controls on the screen, then users won't readily know how to trigger the event. That being said, you can use a timer to delay the screen closing from a KeyPress event.
Public Class EditCustomerInfo
Private WithEvents userInputDelay As Timer = New Timer() With {.Interval = 1000} REM 1 second delay for next user input
Public ReadOnly Property CustomerId As String
Get
Return CustomerIDTextBox.Text
End Get
End Property
Private Sub CustomerIDTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles CustomerIDTextBox.KeyPress
userInputDelay.Enabled = False
REM Reset the timer
userInputDelay.Enabled = True
End Sub
Private Sub userInputDelay_Tick(sender As Object, e As KeyPressEventArgs) Handles userInputDelay.Tick
If Not CustomerIDTextBox.Text = "" Then
Me.Close()
Else : Me.Hide()
End If
End Sub
End Class
Add a button (Button2) to your Main. The code below will hide Button1 when the EditCustomerInfo.Textbox1.Text value is null/blank/white space. Button2's visibility is always the inverse of Button1.
Private EditCustomerInfoInstance As New EditCustomerInfo
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
EditCustomerInfoInstance.ShowDialog()
Button1.Visible = String.IsNullOrWhiteSpace(EditCustomerInfoInstance.CustomerId)
End Sub
Private Sub Button1_VisibleChanged(sender As Object, e As EventArgs) Handles Button1.VisibleChanged
Button2.Visible = Not Button1.Visible
End Sub

Handle all of an array's events

So I have a class which contains a few controls for easy UI design and it has a custom event which is raised whenever the combo box inside the panel is changed:
Public Class BatInputLine
Inherits System.Windows.Forms.Panel
Public Event SelectionChanged As EventHandler
Protected Overridable Sub OnSelectionChanged(ByVal e As EventArgs)
RaiseEvent SelectionChanged(Me, e)
End Sub
Private Sub NameSet(sender As Object, e As EventArgs)
Handles_cboName.SelectedIndexChanged
PlayerName = _playerNames(_cboName.SelectedIndex)
SelectedIndex = _cboName.SelectedIndex
OnSelectionChanged(EventArgs.Empty)
End Sub
An array of these is declared and the user inputs a number according to how many of these they need on screen on a new Form.
ReDim _batInputs(GetNumberOfbatsmen())
I want to call a sub procedure whenever the SelectionChanged event is raised by any of the instances of BatInputLine in _batInputs(). If I try to write a handler e.g sub doSometing(sender as Object, e As EventArgs) Handles _batInputs(0).SelectionChanged I get an error saying that that the _batInput elements need to be declared with a WithEvents modifier, but I don't quite know how to do them.
a) How can I declare this array where all of the indexes get the WithEvents Modifier?
b) How can I assign a sub procedure that is called when these events are raised, which is in the new form?
Made use of the AddHandler keyword, which I didn't know existed.
for i = 0 to _batInputs.Length -1
AddHandler _batInputs(i).SelectionChanged, AddressOf HandleSelectionChangedEvent
next
Private Sub HandleSelectionChangedEvent
'do something
End Sub

WinForm validation: How do you tell if the form contains a control that did not pass validation?

I have a composite usercontrol that contains a dropdown "Country" control and a checkbox. If the checkbox is selected, I want to display a validation icon with a tooltip msg that informs the user that a country selection is required.
If the user tries to save the changes, I want to check the entire form, including this composite usercontrol, for errors and, if found, cancel the save.
I expected that, in the form, I would be able to call the Me.Validate function and that the function would recursively check for any controls on the form at any level and return a value indicating whether there are errors or not. Instead, the function appears to fire the validation event for all the controls (I guess this is OK) and UNCONDITIONALLY return TRUE.
Calling the Validate method on the composite userControl also behaves the same.
Do I have to write my own recursive function to check or errors on this form?
I included my code in order for people to offer general suggestions, too.
Private Sub ComboOutOfCountry_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ComboOutOfCountry.Validating
ValidateComboOutOfCountry()
End Sub
Private Sub ValidateComboOutOfCountry()
If CheckOutOfCountry.Checked AndAlso _
(ComboOutOfCountry.Value Is Nothing OrElse ComboOutOfCountry.Value = DBCodeConstants.Omited) Then
ErrorProvider1.SetError(ComboOutOfCountry, "Country is required when ""Out of Country"" is selected")
Else
ErrorProvider1.SetError(ComboOutOfCountry, "")
End If
End Sub
Private Sub CheckOutOfCountry_CheckedChanged1(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckOutOfCountry.CheckedChanged
If Not CheckOutOfCountry.Checked Then
ErrorProvider1.SetError(ComboOutOfCountry, "")
End If
End Sub
Private Sub ComboOutOfCountry_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboOutOfCountry.ValueChanged
ValidateComboOutOfCountry() 'Clear error icon immediately if they selected a country
End Sub
You can easily subclass the ErrorProvider to achieve this - see http://dotnetslackers.com/Community/blogs/dsmyth/archive/2007/10/12/custom-error-provider.aspx for an example.

Resources