JavascriptProva

domenica 30 settembre 2012

Aggiunta di elementi in un DIV figlio

Ecco un codice in cui ogni DIV figlio può essere gestito aggiungendovi degli elementi.
Per ora iniziamo solo con uno.
Ho tolto gli "id" in quanto quell'attributo deve essere univoco, e non è corretto attribuire lo stesso "id" a più elementi.
<html>
<head>
<style>
.bordato {
 border: 5px solid black;
 float:left;
}
.bordatorosso {
 border: 5px solid blue;
 
 width:200px;
 
 float:left;
 margin-left:5px;
 padding:5px;
 
}
</style>

<script>
function $(a){
 return (document.getElementById(a));
}

function aggiungiFiglio(elemento){
 var nuovo=document.createElement("div");
 nuovo.innerHTML="<input type='text'>";
 elemento.appendChild(nuovo);
}

</script>
</head>




<body>
<div id="padre" class=bordato>

 <div class=bordatorosso>
 Uno due tre

 </div>
 <div class=bordatorosso>
 <input type='button' value='Aggiungi' onClick=aggiungiFiglio(this.parentNode)>
 

 </div>
 <div class=bordatorosso>
 sette otto nove

 </div>


</div>
</body>
</html>

Ho trovato il modo di affiancare e includere in un contenitore con il solo uso dei fogli di stile.

Dopo un po' di confusione, ritorniamo a vedere come si affiancano gli elementi all'interno di un contenitore.
Ecco:
<html>
<head>
<style>
.bordato {
 border: 10px solid black;
 float:left;
}
.bordatorosso {
 border: 5px solid red;
 
 width:200px;
 
 float:left;
 margin:10px;
 
 
}
</style>

<script>
function $(a){
 return (document.getElementById(a));
}


</script>
</head>




<body>
<div id="padre" class=bordato>

 <div id="figlio1" class=bordatorosso>
 Uno due tre

 </div>
 <div id="figlio1" class=bordatorosso>
 quattro cinque sei

 </div>
</div>
</body>
</html>

GetComputedStyle

Ecco, era GetComputedStyle.
Ripassiamolo...

Ecco un autolink in proposito.


Ho trovato un codice...
<html>
<head>
<style>
.bordato {
 border: 2px solid black;
}
.bordatorosso {
 border: 50px solid red;
 width:"200px";
}
</style>

<script>
function $(a){
 return (document.getElementById(a));
}

function dimensiona(){
 alert(getComputedStyle(document.getElementById("figlio1"), null).getPropertyValue("border-width"));
 
 
}
window.onload=dimensiona;
</script>
</head>




<body>
<div id="padre" class=bordato style="height:200px;width:800px">

 <div id="figlio1" class=bordatorosso>
 </div>


</div>
</body>
</html>

sabato 29 settembre 2012

Creazione di DIV padri e figli in un documento

Architettare un sistema in cui si aggiungono figli a un elemento, i quali passano, all'occorrenza, a un altro elemento...
Come ho già fatto, è necessario predisporre delle funzioni che permettano di fare rapidamente riferimento al genitore e a degli specifici fratelli.

Costruire un div con due div figli posti in esso, affiancati.
<html>
<head>
<style>
.bordato {
 border: 2px solid black;
}
.bordatorosso {
 border: 2px solid red;
}
</style>

<script>

</script>
</head>




<body>
<div id="padre" class=bordato style="height:200px;width:800px">
 <div id="figlio1" class=bordatorosso style="height:200px;width:400px">
 </div>


</div>
</body>
</html>
Ecco un primo rudimentale tentativo di costruire un genitore con un figlio, fatto dando volta per volta le misure, cosa che dovrà essere eliminata concentrando le istruzioni relative alla formattazione in poche istruzioni buone per tutta la pagina.


C'è un primo limite: il bordo del figlio si estende oltre il bordo del padre.
Ricordo che c'erano delle definizioni di attributi di stile che tenevano conto del bordo degli elementi, ma non ricordo precisamente quali...

domenica 23 settembre 2012

Due funzioni utili per i blocchi che voglio creare nel mio programma

Ho elaborato due funzioni, una già presente in qualche libreria di JavaScript, che risparmia di scrivere il document.getElementById, e un'altra che permette di isolare gli elementi all'interno dell'innerHTML di un elemento.
Questo è il codice completo di prova che ho usato.
Le funzioni andranno poi messe in una libreria a parte.
<html>
<head>
<script>
function $(a){
 return (document.getElementById(a));
}
function Sottoelemento(elemento,nome){
 return ($(elemento).querySelector("div[id="+nome+"]"));
}


function funzione(){
  $("mioDiv").innerHTML="<div id='ciccio'>uno</div><div id='pippo'>due</div>";
  alert(Sottoelemento("mioDiv","ciccio").innerHTML);
  alert(Sottoelemento("mioDiv","pippo").innerHTML);
}
window.onload=funzione;
</script>
</head>
<body>
<div id="mioDiv"></div>
</body>
</html>

Aggiunta di elementi che possono essere selettivamente eliminati.

Ecco un codice che aggiunge elementi ognuno dei quali possiede un pulsante che lo elimina dalla serie.
<html>
<head>
<style>
.tipo {
 border:2px solid black;
 width: 300px;
}
</style>
<script>
var contatore=0;
function crea(){
 
 var nuovo=document.createElement("div");
 nuovo.setAttribute("class","tipo")
 nuovo.setAttribute("id",contatore)
 nuovo.innerHTML="<input type='text'><input type='button' id="+contatore+" onClick='elimina(this.id)'>"
 document.getElementById("primo").appendChild(nuovo);
 contatore++;
 
}
function elimina(n){
 var eliminato=document.getElementById(n);

 primo.removeChild(eliminato);
}

</script>
</head>
<body>
<div id ="primo">Elemento</div>

<input type="button" value="aggiungi" onClick="crea()">
</body>
</html>

Eliminazione di elementi precedentemente aggiunti.

Ecco un codice per eliminare un elemento di quelli precedentemente aggiunti:
<html>
<head>
<style>
.tipo {
 border:2px solid black;
 width: 300px;
}
</style>
<script>
var contatore=0;
function crea(){
 for (n=0; n<10;n++) {
  var nuovo=document.createElement("div");
  nuovo.setAttribute("class","tipo")
  nuovo.setAttribute("id",contatore)
  nuovo.innerHTML="ciccio"+contatore;
  document.getElementById("primo").appendChild(nuovo);
  contatore++;
 }
}
function elimina(){
 var eliminato=document.getElementById(3);
 primo.removeChild(eliminato);
}
window.onload=crea;
</script>
</head>
<body>
<div id ="primo">Elemento</div>
<input type="button" value="elimina" onClick="elimina()">

</body>
</html>

Creazione e aggiunta di nuovi elementi HTML

Ecco, ho trovato il modo di creare dinamicamente diversi elementi nuovi in una pagina HTML:
<html>
<head>
<style>
.tipo {
 border:2px solid black;
 width: 300px;
}
</style>
<script>
var contatore=0;
function crea(){
 for (n=0; n<10;n++) {
  var nuovo=document.createElement("div");
  nuovo.setAttribute("class","tipo")
  nuovo.innerHTML="ciccio"+contatore;
  document.getElementById("primo").appendChild(nuovo);
  contatore++;
 }
}
window.onload=crea;
</script>
</head>
<body>
<div id ="primo">Elemento</div>


</body>
</html>
 
E funziona.

venerdì 21 settembre 2012

Un nuovo programmino in JavaScript?

Iniziamo dal meno... E' difficile avere chiare le caratteristiche di funzionamento di un nuovo programma dall'inizio, almeno per me.

Sarebbe meglio farlo in Javascript, anche a rischio di farsi fregare il codice... anche se nell'ambiente non c'è sicuramente nessuna persona che non solo non ha alcuna cognizione di JavaScript o finanche della sua esistenza, ma non sa nemmeno che il codice può semplicemente essere letto con "visualizza sorgente" o aprendo la pagina web con il blocco note...

Dunque, per iniziare ho un foglio in cui si debbono aggiungere dei nomi.
Un tasto "Aggiungi", premendo il quale si apre una textbox nella quale digitare un nome, che si auspica possa diventare immodificabile una volta che il nome sia stato aggiunto a meno di non volerla modificare espressamente con la pressione di un altro tasto.

Inizio con lo scheletro iniziale:
<html>
<head>
<script>


</script>
</head>
<body>


</body>
</html>
Ora devo ricordarmi come si inserisce una textbox.
Ecco:
<html>
<head>
<script>


</script>
</head>
<body>
<input type="text">

</body>
</html>
Come la manovro, adesso?

venerdì 14 settembre 2012

Ho apportato qualche correzione al codice.
Quello che adesso mi serve è regolare la spaziatura fra le caselle.
Cerchiamo di sistemare questi problemi di formattazione delle tabelle prima di affrontare la sezione menu e la nutrita parte relativa ai calcoli...

mercoledì 12 settembre 2012

Estrapolare una parte di una stringa in VB.NET (diverso da VB6)

Un'idea.
Fra il nome e il numero mettere un carattere come un punto.
Così:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim parola As String = "parola.12"

    End Sub
Ora individuare la posizione del punto all'interno della stringa.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim parola As String = "parola.12"
        MsgBox(parola.IndexOf("."))

    End Sub
Ottengo 6, ossia, considerato che la prima lettera è in posizione 0, significa che il punto è al settimo posto.

Ora voglio isolare la parte della stringa che sta dopo il punto.
Ecco, con un po' di tribolazione, dopo aver capito che in VB.NET non esistono più le operazioni Left, Right e Mid:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim parola As String = "parola.12"
        MsgBox(parola.Substring(parola.Length - (parola.Length - parola.IndexOf(".") - 1)))


    End Sub
Così ottengo ciò che è dopo il punto.
Potrei immettere anche questo codice sotto forma di una funzione nel modulo Funzioni.vb... ma lo vedrò dopo.
...e invece l'ho visto subito perchè è veramente facilissimo:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim parola As String = "parola.12324"
        MsgBox(Numero(parola))


    End Sub
    
    Function Numero(ByVal stringa) As Integer
        Dim s As String = stringa.Substring(stringa.Length - (stringa.Length - stringa.IndexOf(".") - 1))
        Dim n As Integer = CInt(s)
        Return n
    End Function

Simulazione di matrici di controlli: un'idea

Una delle cose che più mi ha sconvolto del nuovo ambiente di programmazione è che non è più possibile creare matrici di controlli!
Pare che non solo io, ma anche fior di programmatori professionisti si siano trovati in difficoltà per questo.
Uno degli artifizi che ho trovato spulciando alla ricerca di soluzioni al problema è quello di apporre alla proprietà Name del controllo un numero, in modo da usarlo come indice di una matrice di controlli.
Posso sperimentare sullo scheletro del mio programma qualcosa del genere...

Per intanto, diamo un Nome ai controlli che ho creato.
    Sub disponiCaselle(Of T As New)(ByVal nome As String, ByVal larghezza As Integer, ByVal sinistra As Integer)
        Dim numero As Integer
        numero = DateTime.DaysInMonth(anno, mese)
        Dim cas As Object
        For n = 0 To numero - 1
            cas = New T
            With cas
                .Name = nome & n + 1
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = larghezza
                .Left = sinistra
                .Top = .Height * (n Mod numero)
                .testo = .Name 'GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
                .Scrivi()
            End With
            Me.Controls.Add(cas)
        Next
    End Sub
Sì, ecco. Per fare la prova ho fatto in modo che la proprietà testo di ogni elemento fosse la sua proprietà Name, "commentizzando" il codice che c'era prima per non perderlo.



Ora sto pensando di creare per ciascuna classe una proprietà Index nella quale porre il numero ricavato dalla proprietà Name con un artifizio di manipolazione delle stringhe.
In questo modo, posso far riferimento a ogni elemento con il suo indice, un po' come nel buon (neanche tanto!) vecchio VB6...

Creazione immediata di altre colonne

A questo punto mi bastano pochissimi secondi per creare una nuova colonna giocando liberamente sulle larghezze delle varie colonne. Basta aggiungere un altro elemento alla matrice larghezze, della larghezza voluta, e chiamare un'altra volta il metodo disponiCaselle con il numero del successivo elemento della matrice:
....
    Dim larghezze As Integer() = {150, 100, 100}
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        disponiCaselle(Of Calendario)(larghezze(0), SommaElementiDiArray(larghezze, 0))
        disponiCaselle(Of Casella)(larghezze(1), SommaElementiDiArray(larghezze, 1))
        disponiCaselle(Of Casella)(larghezze(2), SommaElementiDiArray(larghezze, 2))
....
Ed ecco:



Facilissimo!

Creazione di classi derivate, funzioni template e prima realizzazione del calendario.

Ora mi devo cimentare a creare dei derivati di Label, funzione specifica di VB.NET che VB6 si sognava beatamente.
Ereditarietà!!!

Class Casella
    Inherits Label

End Class
Bene.
Praticamente a questo punto si chiama casella ma è praticamente ancora una Label.
Sostituisco Casella a Label nel codice.
    Sub disponiCaselle(ByVal larghezza As Integer, ByVal sinistra As Integer)
        Dim numero As Integer
        numero = DateTime.DaysInMonth(anno, mese)
        Dim cas As Casella
        For n = 0 To numero - 1
            cas = New Casella
            With cas
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = larghezza
                .Left = sinistra
                .Top = .Height * (n Mod numero)
                .Text = GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
            End With
            Me.Controls.Add(cas)
        Next
    End Sub
E ovviamente funziona ancora.

E' possibile aggiungervi delle proprietà?

Provo...

Ecco la mia caselluccia: forte di esperienze già fatte, ho fatto in modo che il codice dapprima imposti la sua proprietà pubblica testo, quindi inneschi il suo metodo Scrivi per fare apparire sulla casella il testo.
Class Casella
    Inherits Label
    Public testo As String
    Sub Scrivi()
        Text = testo
    End Sub
End Class
Ed ecco il codice che la usa:
    Sub disponiCaselle(ByVal larghezza As Integer, ByVal sinistra As Integer)
        Dim numero As Integer
        numero = DateTime.DaysInMonth(anno, mese)
        Dim cas As Casella
        For n = 0 To numero - 1
            cas = New Casella
            With cas
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = larghezza
                .Left = sinistra
                .Top = .Height * (n Mod numero)
                .testo = GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
                .Scrivi()
            End With
            Me.Controls.Add(cas)
        Next
    End Sub


Bene. Adesso voglio fare in modo che sia in qualche modo "passato come parametro" anche il tipo di controllo sul quale deve agire la subroutine disponicaselle.
Ricordo che si deve usare una funzione template o generica, con la parola chiave Of.
Ricordiamo...

In pratica, mi serve una subroutine che agisca con diverse classi di oggetti, in quanto devo poterla usare con una classe o con una classe derivata della prima...

Ecco rinfrescata la memoria.
Si deve mettere As New dopo la Of seguita dalla variabile, e bisogna dichiarare la variabile oggetto As Object.
Ecco:
    Sub disponiCaselle(Of T As New)(ByVal larghezza As Integer, ByVal sinistra As Integer)
        Dim numero As Integer
        numero = DateTime.DaysInMonth(anno, mese)
        Dim cas As Object
        For n = 0 To numero - 1
            cas = New T
Ora posso creare una sottoclasse di Label per la seconda colonna...
Ecco i due oggetti.
Ho creato prima Casella, destinato ad apparire sulla seconda e su eventuali altre colonne con sfondo bianco, successivamente Calendario, destinato ad apparire sulla prima colonna con le date scritte sopra.
Nella prima ho una proprietà testo e un metodo Scrivi che non fa assolutamente nulla (in modo che quando il codice li chiami non generi un errore in quanto inesistenti); il metodo Scrivi viene overridato nella classe derivata Calendario con un metodo Scrivi che invece scrive il valore della proprietà testo.
Class Casella
    Inherits Label
    Public testo As String
    Overridable Sub Scrivi()
    End Sub
End Class

Class Calendario
    Inherits Casella
    Overrides Sub Scrivi()
        Text = testo
    End Sub
End Class
la proprietà testo non viene specificata nella classe derivata Calendario in quanto già presente nella classe genitrice e quindi ereditata.

Ed ecco il codice che chiama per due volte la funzione disponiCaselle, l'una per la classe Calendario, prima colonna, e l'altra per la classe Casella, seconda colonna.
        disponiCaselle(Of Calendario)(larghezze(0), SommaElementiDiArray(larghezze, 0))
        disponiCaselle(Of Casella)(larghezze(1), SommaElementiDiArray(larghezze, 1))
Il risultato è perfetto:

Uso della funzione che somma gli elementi di una matrice

Ed ecco come ho impiegato la mia funzione che somma gli elementi di un array:
Public Class Form1
    Dim mese As Integer = 9
    Dim anno As Integer = 2012
    Dim larghezze As Integer() = {300, 100}
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        disponiCaselle(larghezze(0), SommaElementiDiArray(larghezze, 0))
        disponiCaselle(larghezze(1), SommaElementiDiArray(larghezze, 1))
    End Sub
    Sub disponiCaselle(ByVal larghezza As Integer, ByVal sinistra As Integer)
        Dim numero As Integer
        numero = DateTime.DaysInMonth(anno, mese)
        Dim casella As Label
        For n = 0 To numero - 1
            casella = New Label
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = larghezza
                .Left = sinistra
                .Top = .Height * (n Mod numero)
                .Text = GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
            End With
            Me.Controls.Add(casella)
        Next
    End Sub
End Class
Ho isolato il codice che dispone le caselle in colonna nella subroutine disponicaselle, in modo da poterla richiamare più volte.
Quindi do alla routine due parametri, uno per la larghezza della colonna e uno per la posizione sinistra della colonna.
Ponendo in una matrice le larghezze predeterminate per ciascuna colonna, dalla prima all'ultima, faccio in modo che il primo parametro della subroutine sia il numero dell'elemento della matrice che contiene la larghezza della colonna, e il secondo parametro sia la somma delle larghezze delle colonne precedenti.
Funziona.
In questo modo posso predeterminare le larghezze delle varie colonne semplicemente modificando i valori della matrice larghezze, senza impazzire più di tanto.

Una funzione per sommare elementi di una matrice

Una funzioncina per sommare gli elementi di una matrice.
Mi serve per un'ulteriore evoluzione del mio progetto:

    Function SommaElementiDiArray(ByVal matrice As Integer(), ByVal num As Integer) As Integer
        Dim numero As Integer
        For n = 0 To num - 1
            numero += matrice(n)
        Next
        Return numero
    End Function
L'ho inserita nel modulo Funzioni.vb, e viene richiamata dal codice del Form1 in questo modo, usando un array larghezze:
        Debug.Print(SommaElementiDiArray(larghezze, 1))
si tratta di una prova con la quale faccio stampare il risultato nella finestra immediata. Il primo parametro esprime il nome della matrice, mentre il secondo è l'elemento della matrice prima del quale gli elementi vengono sommati.
La matrice con cui ho fatto la prova è questa:
    Dim larghezze As Integer() = {150, 100, 100}
e con il numero 1 come secondo parametro, ottengo la somma del solo elemento 0 della matrice, ossia 150:
150


Se come parametro metto il 2, invece, ottengo come risultato la somma dell'elemento 0 e dell'elemento 1 della matrice:
        Debug.Print(SommaElementiDiArray(larghezze, 2))
250
Mi servirà per un certo progetto che ho in mente...

Aggiunta del giorno della settimana

Aggiunngo il giorno della settimana.
Per fare questo ho dovuto aumentare la larghezza delle mie caselle rispetto a quella standard predeterminata.
Dim mese As Integer = 9
    Dim anno As Integer = 2012
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Calcolo del numero dei giorni del mese
        Dim numero As Integer

        numero = DateTime.DaysInMonth(anno, mese)



        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = 200
                .Left = 0
                .Top = .Height * (n Mod numero)
                .Text = WeekdayName(Weekday(CDate(n + 1 & "/" & mese & "/" & anno)), , 1) & " " & CDate(n + 1 & "/" & mese & "/" & anno)
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
Ma forse potrei inserire tutto quel po' po' di codice in una funzione usando come parametro la data.
Vediamo di ingegnarci.
Dim mese As Integer = 9
    Dim anno As Integer = 2012
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Calcolo del numero dei giorni del mese
        Dim numero As Integer

        numero = DateTime.DaysInMonth(anno, mese)

        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = 200
                .Left = 0
                .Top = .Height * (n Mod numero)
                .Text = GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
    Function GiornoDellaSettimana(ByVal d As Date) As String
        Dim testo As String = WeekdayName(Weekday(d), , 1) & " " & d
        Return testo
    End Function


Questa funzione posso toglierla di qua per non appesantire il codice del form e metterla in un modulo a parte, magari da dedicare ad altre eventuali funzioni.
(Tolgo i commenti per evitare la scocciatura di rimarcarli in verde ogni volta)

Codice del Form (ci aggiungo anche la definizione della classe Form1):
Public Class Form1
    Dim mese As Integer = 9
    Dim anno As Integer = 2012
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim numero As Integer

        numero = DateTime.DaysInMonth(anno, mese)


        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label

            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Width = 200
                .Left = 0
                .Top = .Height * (n Mod numero)
                .Text = GiornoDellaSettimana(CDate(n + 1 & "/" & mese & "/" & anno))
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
End Class


Codice del modulo Funzioni.vb:
Module Funzioni
    Function GiornoDellaSettimana(ByVal d As Date) As String
        Dim testo As String = WeekdayName(Weekday(d), , 1) & " " & d
        Return testo
    End Function
End Module
E funziona ugualmente, perchè la funzione del modulo è pubblica e quindi viene "vista" dal codice del Form1.

Date come testi delle caselle del calendario

Ora riempiamo le caselle con tutte le date. Prendo il numero n di ordine delle caselle e ci aggiungo 1 dato che inizia con 0 e termina con numero-1, e lo uso come numero del giorno del mese nel contesto della data.
Dichiaro una variabile mese e una anno di tipo integer in modo da poter poi cambiare la definizione del mese e dell'anno in rapporto alle esigenze del programma.
    Dim mese As Integer = 9
    Dim anno As Integer = 2012
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Calcolo del numero dei giorni del mese
        Dim numero As Integer

        numero = DateTime.DaysInMonth(anno, mese)



        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .BackColor = Color.White
                .Left = 0
                .Top = .Height * (n Mod numero)
                .Text = CDate(n + 1 & "/" & mese & "/" & anno)
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
ed ottengo il risultato voluto.

martedì 11 settembre 2012

Calcolo del numero dei giorni del mese

Ecco riscritto il codice che calcola il numero dei giorni del mese.
Mi chiedo se esista un modo più breve per ottenere il numero dei giorni di un mese.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Calcolo del numero dei giorni del mese
        Dim dat, base As Date
        Dim numero As Integer = 1
        Dim mese As Integer = Now.Month
        dat = CDate("1/" & Now.Month & "/" & Now.Year)
        base = dat
        Do
            dat = dat.AddDays(1)
            If dat.Month <> base.Month Then Exit Do
            numero += 1
        Loop



        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .Left = 0
                .Top = .Height * (n Mod numero)
            End With
            Me.Controls.Add(casella)

        Next
    End Sub


Funziona, ma mi chiedo se esista un metodo in VB.NET che mi possa evitare di fare tutto questo casino...

Ho trovato qualcosina. Ora provo...

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Calcolo del numero dei giorni del mese
        Dim numero As Integer
        numero = DateTime.DaysInMonth(2012, 2)



        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .Left = 0
                .Top = .Height * (n Mod numero)
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
Funziona! Ed è molto più breve!!!
(ho provato con febbraio perchè si distingue dagli altri, e quest'anno è pure bisestile!)

Disposizione di elementi in colonna

Riparto da zero.
Ho bisogno di tante labels che vengano messe in colonna, ognuna delle quali rechi la data di un giorno del mese, dal primo all'ultimo giorno.
Inizio con un numero arbitrario 10
 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'numero delle caselle
        Dim numero As Integer = 10
        'definizione della variabile oggetto
        Dim casella As Label

        For n = 0 To numero - 1
            casella = New Label
            'attribuzione delle proprietà alla label appena istanziata
            With casella
                .BorderStyle = BorderStyle.FixedSingle
                .Left = 0
                .Top = .Height * (n Mod numero)
            End With
            Me.Controls.Add(casella)

        Next
    End Sub
Usare il Modulo è ingegnoso.
0/numero dà come resto 0, 1/numero dà come resto 1, 2/numero dè come resto 2, fino a (numero-1)/numero chè dà come resto numero-1.
Per ogni dividendo minore del divisore, l'operazione dà come resto il dividendo stesso. Quindi moltiplicando l'altezza dell'elemento per il resto della divisione fra il numero d'ordine dell'elemento e il numero degli elementi meno uno, e impostando la posizione verticale dell'elemento a questo numero, si ha che il primo elemento è alla posizione altezza x 0, ossia zero, il secondo a altezza x 1, il secondo a altezza x 2 fino all'ultimo, in cui la posizione è altezza x (numero-1).