Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: Peruskysymyksiä VB:stä

Sivun loppuun

Keltanokka [25.09.2011 17:20:13]

#

Morjens,

Keltanokka liikenteessä.. Ensinmäiseksi kieleksi VB:n valitsin (suostuttelun kautta) ja jotain on tullut tehtyä, jotain taas ei ole onnistunut. Pari ihan peruskysymystä on tullut mieleen, jotka eivät ole oikeen onnistuneet :D

1. Checkboxit: Saako sille asetettua arvon jotenkin? Onnistuu toki
If checkbox1.checked = true Then
checkbox1.text = xxx

Mutta entä jos tekstin haluaa pitää samana? Tarkoituksena on tehdä "laskin" joka laskee tuloksen näiden klikattujen laatikoiden avulla. Esim.
Label1.text = 5 * checkbox1.(mikä?) * checkbox2.text * checkbox3.text jne

Koitin yrittää myös:
If checkbox1.checked = true then
label1.text = 5* chechbox1.text

Mutta tämä taas meni sekasin, jos useampi oli klikattuna. (koitin tarkasti kirjottaa kaikki vaihtoehdot, muttei tulosta tullut)

2. label: Klikkaamalla saa tekstin/luvun päivitettyä, mutta mikä on oikea "declaration", että se päivittää se sen itsestään? Sama ongelma progressbarien kanssa, pitää ensin klikata, että arvon saa syötettyä. Eli mites se päivittää itse itsensä?:)
Ja lisätäänpä samaan syssyyn. En ole täysin varma (kun en ole edellisen takia koittanut), mutta miten tehdään:

4 progressbaria (nimet= A, B, C, D) (arvot tietenkin erit)
2 tekstikenttää. (nimet =X, Y)
1 label (/tekstikenttä/yms)

Tämä tulisi tapahtua yhtä aikaa ja jatkua kunnes A tai C on 0.
0.6 * X vähennetään D:stä
0.4 * X vähennetään C:stä
0.6 * Y vähennetään B:stä
0.4 * Y vähennetään A:sta

Jos B menee nollaksi, niin sitten koko Y vähennetään D:stä. (tai jos d menee nollaksi niin sitten koko x)

Lisäys: Unohtui tuo labeli.. eli se sitten näyttäisi jäljelle jääneen A:n tai C:n arvon

Tuli nyt varmaan tarpeeksi epäselvästi, mutta jos se siitä 10:llä lukukerralla aukeais.

Ei enenpää nyt aluksi :D
Kiitos todella paljon neuvoista, ei tarvi kaikkiin osata vastata kerralla. Pienikin neuvo on iso askel.

Grez [25.09.2011 17:36:26]

#

1. Ehdotan että laitat checkboxit arrayhin, listiin tms. tai formin controlsia käyt läpi vaikka foreachilla ja sitten siinä kerrot muuttujaa. Jos sulla on enemmän kuin 1 checkboxi, niin ei ole mitään järkeä kirjoittaa koodia jokaiselle erikseen.

2. Alkuarvon voi määrittää designerin puolella, sen voi myös generoida esimerkiksi formin loadeventissä. Se "declaration" millä ne saa päivittymään on juuri se koodi mitä kirjoitat. Eli jos jostain tapahtumasta on tarkoitus tapahtua jotain, niin käsket sen ajaa haluamasi asian tekevät kirjoittamasi koodit siinä tapahtumassa.

Keltanokka [26.09.2011 18:53:43]

#

pakko kai se on tyhmyytensä tunnustaa.. Ei onnistu ei.

Tuohon 1. :een. Mitä ne listat auttaa? Siistimmän näköinen vaan, itse en muuta eroa löytänyt. Myös on "vain" 5 boxia eli ei siinä kauhea homma ole (ja tämä vielä onnistuukin). Se tekstin jos saisi vaan pysymään omanaan ja luvun omanaan, niin olisi jo todella hyvin. (eli en osaa sitä "oikealla" tavalla tehdä.)

2. Ei onnistu ei.. Voiko joku sanoa esimerkin, miten saa labelin näyttämään laskun tuloksen, niin että se päivittää itse itsensä. Eli jos on aluksi 5 checkboxia klikattuna ja sitten ottaa yhen poissa. Itse joudun tämän jälkeen klikkaamaan tulosta, että se sen päivittää. (eli miten se koodi menee) Tätä koitin värkätä, varmaan kaikki maholliset errorit sain tungettua eikä lopuksi enään avannut koko ikkunaa :D

Hennkka [26.09.2011 19:25:17]

#

Ekaksikin olisi kiva nähdä koodi :)

1. No voit luoda nuo checkbixit näin:

Dim boxit As New List(Of Checkbox)

' Form loadiin
For i = 0 To 4
    Dim uusiBoxi As New Checkbox()

    ' Tähän boxin asetukset
    uusiBoxi.Tag = 5                ' Tähän voi laittaa ihan minkä tahansa arvon

    ' Lisätään formille
    Controls.Add(uusiBoxi)
    ' Ja listaan
    boxit.Add(uusiBoxi)
Next

2. Täh? Siis laitat Label1.Text = 1 + 2 ja sitten tarvittaessa Application.DoEvents()

ps. Käytäthän VB.nettiä?

Grez [26.09.2011 19:32:40]

#

2.

Laitoin formille 5 checboxia CheckBox1 jne ja niille Textiksi numeroita
Lisäksi yhden labelin tulosLabel

Koodi seuraava:

Public Class KeltanokkaGUI

    Private boksit As New List(Of CheckBox)
    Private Sub KeltanokkaGUI_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim ctrl As Control
        For Each ctrl In Me.Controls
            If ctrl.Name.StartsWith("CheckBox") Then boksit.Add(ctrl)
        Next
        Laske()
    End Sub
    Private Sub Laske()
        Dim i As Integer = 5
        For Each b In boksit
            If b.Checked Then i *= Integer.Parse(b.Text)
        Next
        tulosLabel.Text = i.ToString()
    End Sub

    Private Sub CheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles CheckBox1.CheckedChanged, CheckBox2.CheckedChanged, CheckBox3.CheckedChanged, CheckBox4.CheckedChanged, CheckBox5.CheckedChanged

        Laske()
    End Sub
End Class

Grez [26.09.2011 19:39:03]

#

Hennkka kirjoitti:

1. No voit luoda nuo checkbixit näin:

Käsittääkseni ongelma ei ollut checkboxien luonti vaan se että niiden muuttaminen päivittää labelin. Eli tuo esimerkkisi on vallan hyvä, mutta pitäisi vielä laittaa kaikille luoduille checkboxeille CheckedChanged -eventti joka tekee laskemisen.

C#:ssahan se kävisi

uusiBoxi.CheckedChanged += checkBox_CheckedChanged

Mutta VB.Netin syntaksia en nyt jaksaa alkaa selvittämään :(

Hennkka [26.09.2011 19:44:31]

#

Vb.Netissä se menee näin:

AddHandler uusiBoxi.CheckedChanged, AddressOf checkBox_CheckedChanged

Keltanokka [05.10.2011 19:16:12]

#

Täällä taas säätämässä.. eipä mitään ylläolevasta, huomasin jo virheeni. (tai siis sain toisella tavalla toimimaan)

Mutta miten murtoluku tagiin? Esim 1.1 ei käy, eikä myöskään 1,1.
Jos ei mitenkään saa suoraan laitettua, niin tomiiko toisen labelin kautta? Tää on jo kaukana koodikielestä, mutta tätä rataa:

label1.text = i.toString()
Label2.text = label1.text / 100 / jokasta b.checked kohti

Tai jotenkin muuten? :D

Grez [05.10.2011 19:25:42]

#

No siellähän lasketaan kokonaisluvuilla (Integer)

Eli esimerkiksi Dim i As Decimal ja Decimal.Parse ..

1,1 ei muuten ole murtoluku, vaan desimaaliluku. 11/10 olisi murtoluku.

Keltanokka [05.10.2011 20:26:53]

#

Ohops noin käy kun miettii jo vähän pidemmälle kuin kirjottaa :)
Mutta vastauksen sain, kiitos.

Ja sitten perään uutta ;)
Nyt kun desimaalit osuu kohilleen, niin desimaaleja tulee sitten kerralla kunnolla. Eli miten saisi labelin näyttämään vain kokonaislukuja? tai ainakin loppunollat poissa

Grez [05.10.2011 21:20:13]

#

Voit sanoa sille, että haluat pyöristää esim max. 3 desimaalin tarkkuudella..

tulosLabel.Text = i.ToString("0.###")

Tuo laittaisi siis 0-3 desimaalia näkyville riippuen luvusta.

Tai esim. ToString("0") pyöristää kokonaisluvuksi. Kannattaa tutustua decimalin ToStringin dokumentaatioon.

Keltanokka [07.10.2011 22:02:44]

#

Tää alkaa jo suoraan hävettään, kun ei onnistu... :P
Tuo ylläoleva oli taas hyvin selitetty ja se mitä hain, kiitos Grez

Seuraava probleema:
Jos pitäisi saada label.text arvo formista toiseen, niin miten onnistuu?
Progressbar1.value = form1.label1.text

Näinhän, mutta ongelmana on siis se, että kun syötän arvon form1:seen ja suljen sen, ei arvo siirry form 2:seen. (eli se pitäisi saada tallennettua jotenkin)

Tämä auttaa jo paljon, mutta jos seuraavakin onnistuis simppelisti, niin olisi jo todella loistava:
Sama kuin yllä (tallentaa/siirtää/mitä nyt tekeekin), mutta sen lisäksi olisi buttonille komento "tallenna valinnat". Tämä tekisi tietokoneelle tiedoston, johon se tallentaisi siltä (ja vain siltä) formilta labelien tekstit (itse tietenkin määrätty mitkä kaikki).
Mutta ei siinä vielä kaikki :) Tietenkin pitäisi sitten vastaava nappula saada "avaa tiedosto", mutta tämä onkin jo pahempi:

Eri formille pitäisi saada tallennetut luvut (= tallennetaan formilta 1, ladataan formille 2). Jä tästähän sen tulisi automaattisesti sijoittaa oikea luku oikeaan paikkaan. Eli label1.text = progressbar1.value -- label2.text = progressbar2.value yms

En nyt ole varma, onko edes toinen mahdollista, mutta ensinmäiseen neuvominen auttaa jo paljon :)

Grez [07.10.2011 22:32:24]

#

Mielestäni tuo pitäisi mennä ihan suoraviivaisesti form2.label2.Text = label1.Text tms, olettaen että form2 on viittaus siihen toiseen formiin. Muistelisin, että useampi form pyörii oletuksena samassa säikeessä, joten ei tarvitse edes tehdä Invokea..

Keltanokka [07.10.2011 22:53:38]

#

Täytyy sanoa, että joko on jokin pielessä tai sitten se ei noin ole.

Form3:

Private Sub laske1()
        Dim s As Decimal
        s = Form1.Label1.Text
        If CheckBox6.Checked Then
            s += CheckBox6.Tag   *
        End If
        Me.Label2.Text = s.ToString

    End Sub

Tässä joku pielessä? Koitin korvata myös * kohdan form1.label1.text + 100, ei auttanut. Myös "me" kohdan poissa jättäminen ei auta.

"olettaen että form2 on viittaus siihen toiseen formiin" Nyt en täysin varma ole, mitä tarkoit tällä. Lyhyesti, on aloitus ruutu josta saa avattua form 1-3.
1 ja 2 ovat samanlaiset, joista pitäisi tietyt luvut (label.text) saada siirrettyä form3:seen. 1 ja 2 ovat siis "laskimia", joiden tulos siirretään Form3:seen (jossa taas jatkuu laskut vähän eritavalla)

Grez [07.10.2011 23:00:08]

#

Pistä koodit johonkin ladattavaksi, niin voin vilkaista.

Keltanokka [07.10.2011 23:12:41]

#

Nyt en enään ehi niitä laitella, voin huomen aamusta pistää.
Mutta testasin tätä vielä ja huomasin myös, ettei ne labelin tekstit sinne tallentuneet. Eli avasin Form1:n, syötin arvot ja se laski oikean tuloksen. Suljin formin ja avasin uusiksi, tulos oli kadonnut.
Koitin myös pitää molempia formeja yhtäaikaa auki, muttei se siltikään lukua suostunut hakemaan.
Tähän alapuolelle pistän huomenna sen linkin, mistä löytää koko koodinrimpsun (jos tästä ei vielä voi sanoa syytä ;))

Grez [07.10.2011 23:20:58]

#

Millaisella koodilla sitten tallensit ne formin sulkemisen yhteydessä ja millaisella koodilla luit ne takaisin formia uudelleen avatessasi?

Keltanokka [08.10.2011 12:04:27]

#

Tässä siis sitä koodia vähän koitin kysellä :)
Eli rastista / (button.click) me.close komennolla kiinni ja (button.click) Form3.show auki. Eli puuttuu se tallennus koodi.

Ja jos sitä koodia halusit vilkaista, niin tässäpä olisi. Tästä puuttuu aloitus, jossa ei ole kuin 4 nappulaa josta formit saa auki. Form 1 ja 2 ovat samanlaisia, joten en molempia pistänyt. (Ja tämähän on vasta alussa, joten ei se vielä paljoa kerro)
http://snipt.org/xoGj/PHP Default

Grez [08.10.2011 12:21:25]

#

Joo, no tossa koodissa ei näy ne asiat mitkä olisi kiinnostanut vastaamisen kannalta, eli missä formit luodaan ja missä ne pistetään talteen. Ilmeisesti ei sitten missään.

Et tietenkään voi tuolla tavalla viitata luokkaan, vaan sinun täytyy viitata luokan instanssiin eli olioon.

Jaa miksi näin? No ajatellaan että olet avannut neljä Form1:stä näytölle, niin jos kirjoitat vaan Form1, niin eihän kone tiedä mitä niistä neljästä tarkoitat.

Eli jos esimerkiksi olet tehnyt

Dim toka = new Form1()
toka.Show()

Niin sun pitää kirjoittaa sinne koodiin toka.Label1.Text eikä Form1.Label1.Text

Jossakin sun täytyy myös säilöä tuo viittaus, eli esimerkissäni "toka" -muuttuja.

Tai toki sen voi kaivaa esiin, vaikka luontivaiheessa ei olisi pistänytkään viittaust talteen. Ei vaan mielestäni ole kovin kätevä tai järkevä tapa.

Tein esimerkin, missä oli luokat Form1 ja Form2 ja molemmat avataan ja sitten Form1:llä oleva nappi vaihtaa kaikki Form2-luokan instanssien taustavärin: (Tätä vaihtoehtoa en siis suosittele)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    For Each f In My.Application.OpenForms
        If TypeOf f Is Form2 Then
            DirectCast(f, Form2).BackColor = Color.CadetBlue
        End If
    Next
End Sub

Keltanokka [08.10.2011 14:57:38]

#

Grez kirjoitti:

Joo, no tossa koodissa ei näy ne asiat mitkä olisi kiinnostanut vastaamisen kannalta, eli missä formit luodaan ja missä ne pistetään talteen. Ilmeisesti ei sitten missään.

Jaa miksi näin? No ajatellaan että olet avannut neljä Form1:stä näytölle, niin jos kirjoitat vaan Form1, niin eihän kone tiedä mitä niistä neljästä tarkoitat.

Ei missään :D Olen vain rakentanut formit ja koodit kirjoitellut, enkä mitään erikoista siihen naputellut.
Ei ole tarkoitusta avata neljää samanlaista, vain yksi. Form 1 ja form 2 ovat samanlaisia sisällöltään, mutta molemmille on oma koodi ja rakennettu formi. Eli maalaisjärjellä ajateltuna riittää pelkkä Form1.label1.text ? Kun ei niistä siis ole kuin se 1.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Form1.Show()

Eli saako jollakin koodilla tallennettua syötetyt tiedot (checkbox & numericupdown) siihen asti, kun koko homman sulkee? Eli ne säilyisivät vaikka formin sulkeekin välissä.

Grez [08.10.2011 15:23:24]

#

Keltanokka kirjoitti:

Form 1 ja form 2 ovat samanlaisia sisällöltään, mutta molemmille on oma koodi ja rakennettu formi. Eli maalaisjärjellä ajateltuna riittää pelkkä Form1.label1.text ?

Tässä tarvii varmaan sen verran insinöörijärkeä, että tietokoneella ei kannata tehdä samaa työtä kahteen kertaan, kun sen voi kopioidakin. (Ja en nyt tarkoita koodin copy&pasteamista)

Ja se, että sulla nyt sattuu olemaan vain yksi instanssi ei muuta tilannetta mitenkään. Eihän se kone voi tietää, ellet sille määrittele, että sulla ei koskaan tule olemaan kuin se yksi instanssi. Eli sikäli mielestäni maalaisjärjelläkään ei voi ajatella, että Form1.label1.text riittäisi (paitsi jos siis Form1 on viittaus olioon, jota se ei tässä tapauksessa ole)

Keltanokka kirjoitti:

Eli saako jollakin koodilla tallennettua syötetyt tiedot (checkbox & numericupdown) siihen asti, kun koko homman sulkee? Eli ne säilyisivät vaikka formin sulkeekin välissä.

Saa. Ensin päätät mihin haluat ne tiedot tallentaa. Tiedostoon, tietokantaan, nettiin, ohjelman asetustiedostoon, vai johonkin muualle ja sitten toteutat sen tallennuksen.

Keltanokka [08.10.2011 18:31:17]

#

... :D arvaat jo varmaan miten kävi. Tää o vaikeempaa kuin luulin..

Voitko rautalankamallilla sanoa esimerkin mihin ne dimit heitän? Koitin sitä laittaa form3:seen laskun eteen, heti aloitus ikkunaan ja form1:seen. Ei mitään muutosta. Eli ei se luku siirry sieltä formista toiseen. Myös tuossa esimerkki oli aika puhtaasti erilainen kuin omani, eli en siitä paljoa irti saanut.

Ja samaan voisin vielä tallennuksesta kysyä. Miten menee, jos
a) haluan sen tallentavat ne 4 labelin numeroa siihen asti, kun ohjelma suljetaan. Tämä auttaa sen, että jos ikkunan sulkee ja avaa uusiksi, ei tarvi uusiksi syöttää mitään. Eikä erillistä tiedostoa tai nettiin (eli tiedoston sisään?) Tämä siis käytännössä sama kuin alkuperänen ongelma.

b)Haluan sen tallentavan koko homman: kaikki checkboxien arvot, labelit, numericupdownit erilliseksi tiedostoksi, jonka sijainnin tietenkin itse saa päättää. Sittenhän se pitäisi saada avattuakin eli heti ensinmäiseen ikkunaan "load" painike, joka sijoittaa kaikki tallennetut tiedot oikeisiin kohtiin.

Grez [08.10.2011 18:57:58]

#

a) kun ohjelman käynnistää, se varaa .exe-tiedostonsa, joten siihen itseensä kirjoittaminen ei välttämättä edes onnistu. Joka tapauksessa se olisi erittäin huono idea monestakin syystä.

Paljon helpompaa olisi tehdä kuten kaikki muutkin ohjelmat, että tallennetaan johonkin ennalta määriteltyyn paikkaan tiedostoon, tyyliin %appdata%\ohjelmasinimi\tallennustiedostonnimi

Käyttäjän kannaltahan tässä ei ole käytettävyyseroa siihen, että tiedot tallennettaisiin ohjelmaan itseensä.

b) Tämä ei eroa edellisestä muuten kuin siten, että käyttäjä valitsee tiedoston, johon tallennus tehdään ja käynnistää lukemisen napilla.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta