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 Function
Onko 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 Sub
Samalla, 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 Class
Kä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 Class
Public 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 Class
Aihe on jo aika vanha, joten et voi enää vastata siihen.