Ohjelma kysyy käyttäjältä "jatko-ojeita" toimintaan. Käyttäjällä on mahdollista antaa syöte painamalla yhtä neljästä buttonista.
Kokeilin Do luuppia jossa tarkistetaan muuttujan tilasta onko nappia klikattu.
Nappia klikkaamalla saa siis muuttujan tilaa vaihdettua Trueksi.
Jostain syystä en saanut tuota toimimaan.. mitään virheilmoirusta ei tule, mutta ohjelmaa kaatuu debuggauksessa napin klikkauksen jälkeen.
Public Function KäyttäjäKomento()
Do
If Naappi_A_painettu = True Then Return eTehtävä.A : Exit Do
If Naappi_B_painettu = True Then Return eTehtävä.B : Exit Do
If Naappi_C_painettu = True Then Return eTehtävä.C : Exit Do
If Naappi_D_painettu = True Then Return eTehtävä.D : Exit Do
Loop
End FunctionOnko tämä edes hyvä / oikea tapa vastanottaa käyttäjän syötettä?
Ei ole hyvä tapa. Normaali tapa on käyttää tapahtumia (events). Tällä hetkellä formisi säie kelaa tuossa loopissa, eikä pysty sen vuoksi käsittelemään napinpainalluksia. Tästä syystä myös ohjelmasi "kaatuu" kun nappia painetaan -> se ei reagoi napin painallukseen, joten Windows tulkitsee sen olevan sekaisin. Lisäski yhden ytimen cpu-kulutus on tapissa.
Jos välttämättä haluaisit tehdä sen tuolla tavalla, niin loopin sisään pitäisi laittaa System.Windows.Forms.Application.DoEvents(), mutta kannattaa huomata että tuo mahdollistaa minkä tahansa tapahtuman suorittamisen, ei pelkästään noiden nappuloiden onClickien ajoa.
Mites tämä sitten pitäisi toteuttaa?
' ' 'Koodia ' ' If Käyttäjäkomento = eTehtävä.B Then TeeJotain Else If Käyttäjäkomento = eTehtävä.C Then TeeJotainMuuta End If ' ' 'koodia '
Miten voin Buttonin Click -tapahtumasta pukata syötteen tuolle KäyttäjäKomento funktiolle?
Yksi tapa on pitää muistissa, missä vaiheessa prosessi on, ja jatkaa siitä aina, kun käyttäjä on antanut syötteensä.
Sub toiminto
If vaihe = 1 Then
' Tee jotain
vaihe = 2
Kysy "Mitäs nyt tehdään?"
Else If vaihe = 2 Then
If painettu Then tee_jotain
vaihe = 3
Kysy "Ja mitä nyt?"
Else If vaihe = 3 Then
' Ja niin edelleen.
End If
End SubSamalla, kun rekisteröit napinpainalluksen ja tallennat tiedon muuttujaan, voit kutsua uudestaan tuota funktiota, jolloin toiminta jatkuu.
Käyttöliittymäsuunnittelua ehkä voisi myös miettiä joltain muulta kannalta. Eli miksi täytyy ensin käynnistää toiminta (oletettavasti painamalla nappia) ja sitten (samalla lomakkeella?) halutaan lisätietoa taas nappia painamalla. Miksei käyttäjä paina suoraan yhtä neljästä napista? Toisaalta jos kyseessä on tyypillinen dialogikäyttöliittymä niin tuossa ei ole mitään ongelmaa, kun dialogi voidaan näyttää modaalisti.
Yleisesti olisi hyvä tietää vähän tarkemmin mitä oikeastaan ollaan tekemässä, että pystyisi antamaan toimivia ratkaisuja.
Jep, uusi lomake kehiin vaan. Tässä vähän koodia, pahoitteluni jos on liian valmista.
Public Class FormKysely
Private m_tulos As Integer
Public Sub New()
InitializeComponent()
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedDialog
Me.ControlBox = False
Button1.DialogResult = Windows.Forms.DialogResult.OK
Button2.DialogResult = Windows.Forms.DialogResult.OK
Button3.DialogResult = Windows.Forms.DialogResult.OK
Button4.DialogResult = Windows.Forms.DialogResult.OK
End Sub
Public ReadOnly Property Tulos() As Integer
Get
Return m_tulos
End Get
End Property
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
m_tulos = 1
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
m_tulos = 2
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
m_tulos = 3
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
m_tulos = 4
End Sub
End ClassKäyttö:
Dim valinta As Integer
Dim valintaIkkuna As New FormKysely()
With valintaIkkuna
.ShowDialog(Me)
valinta = .Tulos
.Dispose()
End With
MsgBox("Valitsit: " & valinta)Jep.. vesimiehen ehdottama ratkaisuhan siihen projektiin piti näpertää. Alunperinkin kyllä mietin tuota jatko-ohjeiden kysymistä dialogilla, mutta hylkäsin ajatuksen, koska mm. parentformia ei kyselyn aikana voi käyttää (vai voiko?). Ratkaisu on mielestäni hieman kömpelö.
Eikö siis ole keinoa keskeyttää ajoa kunnes käyttäjä antaa syötteen buttonilla?
Mitä vikaa minun esittämässäni tavassa sitten on? Ei siitä paljon helpommalla pääse. Säikeillä myös pysäyttäminen on (kai yhä?) mahdollista, mutta sitä ominaisuutta ei kannata hyödyntää, ennen kuin tiedostaa monisäikeisyyden (ja etenkin säikeen pysäyttämisen) riskit.
MORJENS taas novice!
Metabolix'n esittämä malli toimii...
Public Partial Class MainForm
Dim frm As Object = Nothing
Public Sub New()
Me.InitializeComponent()
End Sub
Sub MainFormLoad(sender As Object, e As EventArgs)
frm = New frmKysely
frm.ShowDialog
End Sub
Public Shared Sub toiminto(ctl As Button)
MsgBox(ctl.Parent.Name & "." & ctl.Name)
'Select Case Cint(ctl.Name.ToLower.Replace("button", ""))
'Case 1
'MsgBox("tee jotain")
'Case 2
'MsgBox("tee jotain muuta")
'Case 3
'jne.
'Case 4
'jne.
'End Select
ctl.Parent.Dispose
End Sub
End ClassPublic Partial Class frmKysely
Public Sub New()
Me.InitializeComponent()
End Sub
Sub Button1Click(sender As Object, e As EventArgs)
MainForm.toiminto(sender)
End Sub
Sub Button2Click(sender As Object, e As EventArgs)
MainForm.toiminto(sender)
End Sub
Sub Button3Click(sender As Object, e As EventArgs)
MainForm.toiminto(sender)
End Sub
Sub Button4Click(sender As Object, e As EventArgs)
MainForm.toiminto(sender)
End Sub
End ClassAihe on jo aika vanha, joten et voi enää vastata siihen.