Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: For Each ongelma vb2010

Nikkari [27.10.2011 09:34:44]

#

En löydä millään ratkaisua kuinka saisin For Each silmukan pyörimään määrätyssä järjestyksessä. Minulla on kymmeniä kuvakehyksiä,joissa on kuva ja jotka on luotu dynaamisesti. Siirtelen kuvia kehysten välillä ja lopuksi siirrän kuvat For Each silmukalla uuteen säännölliseen järjestykseen, niin tämä silmukka ei käy läpi näitä kuvakehyksiä säännöllisessä järjestyksessä, vaan sijoittaa ensin noin kymmenen kuvaa kehyksiin jossakin satunnaisessa järjestyksessä, ennen kuin sijoitta loput "suurimmasta" pienimpään niin kuin pitäisi tehdä kaikkien kuvien kohdalla (kuvien nimenä on numero). Jos en siirrä kuvia ollenkaan ennen uutta jakoa menee jako aivan oikein, eli kuvien siirtely sekoittaa jotenkin tämän silmukan järjestyksen.
Voiko jotenkin määrätä silmukan käsittelyjärjestyksen, tai olisiko tähän ongelmaan joku muu ratkaisu.
Miksi tämä silmukka pyörii väärinpäin?

Grez [27.10.2011 09:44:37]

#

For Eachän ei ole semanttisesti tietyssä järjestyksessä läpi käyvä, vaan sananmukaisesti "jokaiselle". Eli periaatteessa jos ympäristön rajoitteet ei haittaisi, niin ne voitaisiin ajaa vaikka kaikki yhtäaikaa.

For Eachia voi käyttää IEnumerable rajapinnalle, ja se toimii sisäisesti seuraavasti:

Dim enumerator As IEnumerator(Of T) = läpikäytävät.GetEnumerator()
Try
	While enumerator.MoveNext()
		Dim yksilö As T = enumerator.Current
		'Oma foeachin sisällä oleva koodisi on tässä välissä
	End While
Finally
	Dim disposable As IDisposable = TryCast(enumerator, System.IDisposable)
	If disposable IsNot Nothing Then
		disposable.Dispose()
	End If
End Try

Nikkari kirjoitti:

Voiko jotenkin määrätä silmukan käsittelyjärjestyksen, tai olisiko tähän ongelmaan joku muu ratkaisu.

Jos haluat käsitellä ne jossain muussa järjestyksessä, kuin mitä käyttämäsi läpikäytävä (IEnumerablen toteuttava) luokka niitä antaa, niin voit toki tehdä perinteisen For-silmukan. Se olisi myös semanttisesti loogisempi vaihtoehto, jos järjestyksellä on väliä.

Nikkari kirjoitti:

Miksi tämä silmukka pyörii väärinpäin?

Ei se pyöri väärin päin, kun et ole määritellyt sille mitään järjestystä. Se ehkä pyörii eri päin kuin luulit tai haluaisit, mutta kun et ole pyytänyt tiettyä järjestystä vaan käyttänyt For Eachia, niin eihän se väärin ole.

Käytännössä järjestys määräytyy käyttämäsi läpikäytävän luokan toteutuksen mukaisesti. Ja kun et maininnut mitä luokkaa käytät kuvakehyksien säilömiseen, niin mahdoton sanoa.

Nikkari [27.10.2011 16:03:11]

#

Kiitos vastauksesta.
Lisäsin antamasi koodin For Each silmukkaani. Siinä on joku propleema, jos kirjoitan tämän muuttujamäärityksen näin: Dim enumerator As IEnumerator(Of PictureBox) = MyObject.GetEnumerator(), niin Picturebox ei kelpaa laittamasi T:n paikalle, vai pitääkö se olla joku muu?
Tässä on tämä koko ohjelman pätkä.

Private Sub uusjako()
        Dim st As String
        Dim mo, kp, stn, mon, maara, laskuri As Integer
        'jaetaan jäljellä olevat kortit uudelleen
        mon = uusijako.Items.Count 'montako korttia on jäljellä
        laskuri = mon - 1 'korttien määrä-1
        maara = mon 'korttien määrä
        For t = 0 To jakon.Items.Count
            jakon.Items.Clear()
            uusikohde.Items.Clear()
        Next

        For Each MyObject As Object In Me.Controls 'Käy läpi kaikki kontrollit formilla

            Dim enumerator As IEnumerator(Of PictureBox) = MyObject.GetEnumerator()
            Try
                While enumerator.MoveNext()
                    Dim yksilö As PictureBox = enumerator.Current

            st = MyObject.name
            stn = Val(st) 'nimi numerona
            If maara > 0 And stn <= mon Then
                If stn > 0 Then jakon.Items.Add(st) 'listaan paikka jonne kortti laitetaan
                kp = kp + 1
                mo = uusijako.Items(laskuri) 'kortinnumero
                MyObject.image = Korttipakka.Images(mo)
                MyObject.visible = True
                MyObject.tag = mo
                maara = maara - 1
                laskuri = laskuri - 1
                uusikohde.Items.Add(mo)
                Select Case stn 'nämä kortit nurinpäin
                    Case 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 18, 19, 20, 21, 26, 27, 28, 34, 35, 42
                        MyObject.image = Korttipakka.Images(0)
                        MyObject.backcolor = Color.Red
                End Select
            End If

                End While
            Finally
                Dim disposable As IDisposable = TryCast(enumerator, System.IDisposable)
                If disposable IsNot Nothing Then
                    disposable.Dispose()
                End If
            End Try

        Next
        pelit = pelit + 1
        pelikierros.Text = pelit
    End Sub

Grez [27.10.2011 16:06:29]

#

Voihan jee. Jospa luet hieman tarkemmin mitä kirjoitin.

Kirjoitin:
"For Each toimii sisäisesti seuraavasti:".

En kirjoittanut:
"Lisää seuraava koodi For Eachisi sisään niin se lukee ajatuksesi ja toimii haluamassasi järjestyksessä:"

Sitten alkuperäiseen kysymykseen ja koodiin, niin missäköhän mielestäsi tuossa määrittelet sen "oikean järjestyksen", jossa haluaisit niiden tulevan?

Ja T on geneerinen tyyppi. Tietenkään se ei toimi sellaisenaan geneerisen tyypin funktion/luokan ulkopuolella. Mutta sillä ei ole väliä kun tarkoitus todellakaan ei ollut tunkea sitä koodia For Eachin sisään. Jos se toimisia niin sinulla olisi vain kaksi sisäkkäistä For Eachia.

Nikkari [28.10.2011 05:33:50]

#

Katsos, kun minä en ole ohjelmoinnin ammattilainen, vaan tällainen ohjelmointia opetteleva vaari, niin en tiedä oikein hyvin näistä kuvioista.
Kiitos kuitenkin hyvistä vastauksista.

Metabolix [28.10.2011 07:38:08]

#

Itse ongelman varmaan ratkaisisi, jos et käyttäisi silmukassa Me.Controlsia vaan tekisit laatikoista oman taulukon tai listan.

Vastaus

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

Tietoa sivustosta