Newsgroup: it.comp.lang.visual-basic
Titolo: [.NET] buco in visual basic?

Ho creato questo form appositamente per farvi vedere l'anomalia che ho
trovato.
Praticamente ho creato una funzione che va inserita nella keydown di
una textbox che dovrebbe facilitare l'inserimento della data.
Infatti quando si inserisce un carattere valido compare immediatamente
il formato della data __/__/____ e mano a mano che si inserisce le
barre vengono lasciate.
Se qualcuno vuole provi ad inserire una data (senza utilizzare il
tastierino numerico xchè non l'ho ancora configurato) e vedrà che
tutto funzionerà perfettamente.
Il problema sorge quando, inserita completamente tutta la data, si
vuole cancellare l'ultimo carattere con il backspace.
Infatti non si sa per quale oscuro motivo vengono cancellati due
caratteri e se si continua il programma si inchioda giustamente perchè
non ritrova il testo dove dovrebbe.
A questo punto secondo me c'è un buco.
Infatti se si lancia in modalità di debug passo passo funziona tutto
perfettamente e la proprietà txtdata.text alla fine del codice è
quella giusta cioè con un solo carattere in meno. Però poi a video ne
toglie due!!!!!!!!
Peggio ancora se si spunta messagebox il che fa comparire una
messagebox ogni volta che si inserisce del testo. Qui funziona tutto
perfettamente!!!!!!!
Naturalmente non è che posso lasciare il programma con una messagebox
Public Class Form1
    Inherits System.Windows.Forms.Form
#Region " Codice generato da Progettazione Windows Form "
    Public Sub New()
        MyBase.New()
        'Chiamata richiesta da Progettazione Windows Form.
        InitializeComponent()
        'Aggiungere le eventuali istruzioni di inizializzazione dopo
la chiamata a InitializeComponent()
    End Sub
    'Form esegue l'override del metodo Dispose per pulire l'elenco dei
componenti.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
    'Richiesto da Progettazione Windows Form
    Private components As System.ComponentModel.IContainer
    'NOTA: la procedura che segue è richiesta da Progettazione Windows
Form.
    'Può essere modificata in Progettazione Windows Form.  
    'Non modificarla nell'editor del codice.
    Friend WithEvents txtdata As System.Windows.Forms.TextBox
    Friend WithEvents chkMessagebox As System.Windows.Forms.CheckBox
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
        Me.txtdata = New System.Windows.Forms.TextBox
        Me.chkMessagebox = New System.Windows.Forms.CheckBox
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label3 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'txtdata
        '
        Me.txtdata.Location = New System.Drawing.Point(60, 84)
        Me.txtdata.MaxLength = 10
 
Me.txtdata.Name
 = "txtdata"
        Me.txtdata.Size = New System.Drawing.Size(152, 20)
        Me.txtdata.TabIndex = 0
        Me.txtdata.Text = ""
        '
        'chkMessagebox
        '
        Me.chkMessagebox.Location = New System.Drawing.Point(92, 8)
 
Me.chkMessagebox.Name
 = "chkMessagebox"
        Me.chkMessagebox.Size = New System.Drawing.Size(20, 20)
        Me.chkMessagebox.TabIndex = 1
        '
        'Label1
        '
        Me.Label1.AutoSize = True
        Me.Label1.Location = New System.Drawing.Point(132, 12)
 
Me.Label1.Name
 = "Label1"
        Me.Label1.Size = New System.Drawing.Size(112, 16)
        Me.Label1.TabIndex = 2
        Me.Label1.Text = "Vuoi la messagebox?"
        '
        'Label2
        '
        Me.Label2.AutoSize = True
        Me.Label2.Location = New System.Drawing.Point(4, 48)
 
Me.Label2.Name
 = "Label2"
        Me.Label2.Size = New System.Drawing.Size(277, 16)
        Me.Label2.TabIndex = 3
        Me.Label2.Text = "Inserire una data senza utilizzare il
tastierino numerico"
        '
        'Label3
        '
        Me.Label3.Location = New System.Drawing.Point(16, 136)
 
Me.Label3.Name
 = "Label3"
        Me.Label3.Size = New System.Drawing.Size(256, 120)
        Me.Label3.TabIndex = 4
        Me.Label3.Text = "Nell'inserimento di una data non ho problemi
ma quando poi sono alla fine e vogli" & _
        "o che l'ultimo carattere sia cancellato premendo backspace mi
vengono cancellati" & _
        " due numeri. La cosa strana è che a livello di debug segnala
proprietà txtdata.t" & _
        "ext con solo un carattere cancellato ma a video non è così.
Inoltre se inserisco" & _
        " una messagebox nella textchanged tutto funziona
perfettamente anche a video"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.chkMessagebox)
        Me.Controls.Add(Me.txtdata)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
    End Sub
#End Region
    Private Sub txtdata_TextChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles txtdata.TextChanged
        If chkMessagebox.Checked Then
            MessageBox.Show("Adesso funziona")
        End If
    End Sub
    Public Function ImmettiData(ByVal Txt As TextBox, ByVal KeyAscii
As Integer) 'As Integer
        Dim AsciiCar As Integer
        Dim Stringa As String
        Dim Partenza As Integer
        Dim Conta As Integer
        Dim Messi As Integer
        Dim Posizione As Integer
        Dim stringa2 As String
        ImmettiData = 0
        If Txt.ReadOnly Then
            Exit Function
        End If
        AsciiCar = KeyAscii
        KeyAscii = 0
        Stringa = Txt.Text
        Partenza = Txt.SelectionStart
        Posizione = Txt.SelectionStart
        If AsciiCar <> 8 Then
            If AsciiCar < 48 Or AsciiCar > 57 Then
                AsciiCar = 0
                Exit Function
            End If
        End If
        If Trim(Stringa) = "" Then
            Stringa = "__/__/____"
        Else
            If Stringa.Length = 1 Then
                Stringa = Stringa & "_/__/____"
            End If
        End If
        If AsciiCar <> 8 Then
            Partenza = InStr(Stringa, "_")
            If Partenza = 0 Then
                Partenza = Txt.SelectionStart + 1
                If Partenza > 10 Then
                    Partenza = 10
                Else
                    If Partenza = 3 Or Partenza = 6 Then
                        Partenza = Partenza + 1
                    End If
                End If
            Else
                Posizione = Posizione + 1
                If Posizione > 0 And Partenza > Posizione Then
                    Scrollasx(Stringa, Posizione)
                    Partenza = Posizione
                    If Partenza = 3 Or Partenza = 6 Then
                        Partenza = Partenza + 1
                    End If
                End If
            End If
            Mid(Stringa, Partenza, 1) = Chr(AsciiCar)
            Txt.Text = Stringa
            Txt.SelectionStart = Partenza
        Else
            If Txt.SelectionLength = 10 Then
                Stringa = "__/__/____"
                Txt.Text = Stringa
                Txt.SelectionStart = 0
                Exit Function
            End If
            If Partenza = 0 Then
                Partenza = 1
            End If
            If Partenza = 3 Or Partenza = 6 Then
                Partenza = Partenza - 1
            End If
            If Partenza > 0 Then
                Mid(Stringa, Partenza, 1) = "_"
                ScrollaDx(Stringa, Partenza)
                Txt.Text = Stringa
                'ImmettiData = Partenza - 1
                Txt.SelectionStart = Partenza - 1
            Else
                Mid(Stringa, 1, 1) = "_"
                Txt.Text = Stringa
                'ImmettiData = 1
                Txt.SelectionStart = 1
            End If
        End If
    End Function
    Private Sub ScrollaDx(ByVal stringa As String, ByRef partenza As
Integer)
        Dim stringa2 As String
        Dim conta As Integer
        Dim messi As Integer
        stringa2 = ""
        For conta = partenza To 10
            If conta <> 3 And conta <> 6 Then
                If Mid(stringa, conta, 1) <> "_" Then
                    stringa2 = stringa2 & Mid(stringa, conta, 1)
                End If
            End If
        Next conta
        If stringa2 = "" Then
            Exit Sub
        End If
        messi = 0
        For conta = partenza To 10
            If conta <> 3 And conta <> 6 Then
                messi = messi + 1
                If messi <= Len(stringa2) Then
                    Mid(stringa, conta, 1) = Mid(stringa2, messi, 1)
                Else
                    Mid(stringa, conta, 1) = "_"
                End If
            End If
        Next conta
    End Sub
    Private Sub Scrollasx(ByVal stringa As String, ByRef posizione As
Integer)
        Dim stringa2 As String
        Dim conta As Integer
        Dim messi As Integer
        stringa2 = ""
        For conta = posizione To 10
            If Mid(stringa, conta, 1) <> "/" And Mid(stringa, conta,
1) <> "_" Then
                stringa2 = stringa2 + Mid(stringa, conta, 1)
            End If
        Next conta
        If stringa2 = "" Then
            Exit Sub
        End If
        messi = 0
        For conta = posizione + 1 To 10
            If conta = 3 Or conta = 6 Then
                Mid(stringa, conta, 1) = "/"
            Else
                messi = messi + 1
                Mid(stringa, conta, 1) = Mid(stringa2, messi, 1)
            End If
        Next conta
    End Sub
    Private Sub txtdata_KeyDown(ByVal sender As Object, ByVal e As
System.Windows.Forms.KeyEventArgs) Handles txtdata.KeyDown
        ImmettiData(txtdata, e.KeyValue)
    End Sub
End Class

 A questo punto secondo me c'è un buco.
No, direi di no.
L'ho "tradotto" in VB6, provato e corretto
KeyAscii va passato ByRef a ImmettiData, non ByVal, viceversa l'evento che
sente la pressione del BackSpace lo esegue a sua volta (un'altra volta). Con
ByRef tu lo azzeri e quindi in quell'evento non ha effetti:
Public Function ImmettiData(ByVal Txt As TextBox, ByRef KeyAscii As Integer)
'As Integer
    Dim AsciiCar As Integer
    Dim stringa As String
    Dim partenza As Integer
    Dim conta As Integer
    Dim messi As Integer
    Dim posizione As Integer
    Dim stringa2 As String
    ImmettiData = 0
    AsciiCar = KeyAscii
    KeyAscii = 0
    stringa = Txt.Text
    partenza = Txt.SelStart
    posizione = Txt.SelStart
    If AsciiCar <> 8 Then
        If AsciiCar < 48 Or AsciiCar > 57 Then
            AsciiCar = 0
            Exit Function
        End If
    End If
    If Trim(stringa) = "" Then
        stringa = "__/__/____"
    Else
        If Len(stringa) = 1 Then
            stringa = stringa & "_/__/____"
        End If
    End If
    If AsciiCar <> 8 Then
        partenza = InStr(stringa, "_")
        If partenza = 0 Then
            partenza = Txt.SelStart + 1
            If partenza > 10 Then
                partenza = 10
            Else
                If partenza = 3 Or partenza = 6 Then
                    partenza = partenza + 1
                End If
            End If
        Else
            posizione = posizione + 1
            If posizione > 0 And partenza > posizione Then
                Call Scrollasx(stringa, posizione)
                partenza = posizione
                If partenza = 3 Or partenza = 6 Then
                    partenza = partenza + 1
                End If
            End If
        End If
        Mid(stringa, partenza, 1) = Chr(AsciiCar)
        Txt.Text = stringa
        Txt.SelStart = partenza
    Else
        If Txt.SelLength = 10 Then
            stringa = "__/__/____"
            Txt.Text = stringa
            Txt.SelStart = 0
            Exit Function
        End If
        If partenza = 0 Then
            partenza = 1
        End If
        If partenza = 3 Or partenza = 6 Then
            partenza = partenza - 1
        End If
        If partenza > 0 Then
            Mid(stringa, partenza, 1) = "_"
            Call ScrollaDx(stringa, partenza)
            Txt.Text = stringa
            Txt.SelStart = partenza - 1
        Else
            Mid(stringa, 1, 1) = "_"
            Txt.Text = stringa
            Txt.SelStart = 1
        End If
    End If
End Function
Private Sub ScrollaDx(ByVal stringa As String, ByRef partenza As Integer)
    Dim stringa2 As String
    Dim conta As Integer
    Dim messi As Integer
    stringa2 = ""
    For conta = partenza To 10
        If conta <> 3 And conta <> 6 Then
            If Mid(stringa, conta, 1) <> "_" Then
                stringa2 = stringa2 & Mid(stringa, conta, 1)
            End If
        End If
    Next conta
    If stringa2 = "" Then Exit Sub
    messi = 0
    For conta = partenza To 10
        If conta <> 3 And conta <> 6 Then
            messi = messi + 1
            If messi <= Len(stringa2) Then
                Mid(stringa, conta, 1) = Mid(stringa2, messi, 1)
            Else
                Mid(stringa, conta, 1) = "_"
            End If
        End If
    Next conta
End Sub
Private Sub Scrollasx(ByVal stringa As String, ByRef posizione As Integer)
    Dim stringa2 As String
    Dim conta As Integer
    Dim messi As Integer
    stringa2 = ""
    For conta = posizione To 10
        If Mid(stringa, conta, 1) <> "/" And Mid(stringa, conta, 1) <> "_"
Then
            stringa2 = stringa2 + Mid(stringa, conta, 1)
        End If
    Next conta
    If stringa2 = "" Then Exit Sub
    messi = 0
    For conta = posizione + 1 To 10
        If conta = 3 Or conta = 6 Then
            Mid(stringa, conta, 1) = "/"
        Else
            messi = messi + 1
            Mid(stringa, conta, 1) = Mid(stringa2, messi, 1)
        End If
    Next conta
End Sub
Private Sub Form_Load()
    Me.txtdata.MaxLength = 10
    Me.txtdata.TabIndex = 0
    Me.txtdata.Text = ""
End Sub
Private Sub txtdata_KeyPress(KeyAscii As Integer)
    Call ImmettiData(txtdata, KeyAscii)
End Sub

[*Lupo* = 
LupoOrmaiR...@libero.it
 in
news:bkphdo$4eagv$
1...@ID-174464.news.uni-berlin.de
] ha scritto:
PS: E la gestione del tasto Canc e, magari, delle freccette di spostamento,
oltre che Home, End e compagnia bella?

Non ti sei accorto che premendo i tasti hai un beep? (classico sintomo di
key non gestita...)
Il comportamento e' corretto, si tratta solo di capire meglio come funziona
VB.NET
, l'apparente problema e' dovuto al fatto che e' vero si che tu agisci
nel KeyPress e gestisci tutta la logica dei tasti, pero' e' anche vero che
dopo aver eseguito la tua routine 
VB.NET
 invoca la KeyDown la quale viene
normalmente processata inviando alla textbox il carattere che tu hai appena
premuto causando lo 'strano' doppione.
Prova ad inserire:
 Private Sub txtdata_KeyPress(ByVal sender As Object, ByVal e As
System.Windows.Forms.KeyPressEventArgs) Handles txtdata.KeyPress
      e.Handled = True
   End Sub
Ad indicare al framework che quell'evento e' gia' stato gestito da te e
vedrai che il tutto si sistema...
HTH
-- 
Corrado Cavalli [Microsoft .NET MVP-MCP]
UGIdotNET - 
http://www.ugidotnet.org
Weblog: 
http://www.ugidotnet.org/710.blog
PS: Non so se il codice e' un porting ma ti consiglierei di usare le
funzioni messe a disposizione dal framework invece di usare i wrapper
(pienamente leciti comunque) che 
VB.NET
 mette a disposizione (e che comunque
altro non fanno che chiamare i metodi nativi), mi riferisco alle varie
funzioni Mid,Left... che possono essere sostituire dai vari metodi messi a
disposizione dalla classe String...

 
Grazie mille
appena torno al lavoro dopo il pranzo provo a vedere se è questo il problema

 HTH
Bravissimo hai centrato in pieno il problema e adesso funziona tutto
perfettamente.
Ti ringrazio č stato un bell'aiuto per la mia tesi
Claudio

...

Prima volevo risolvere questo problema e poi gestire gli altri tasti.
Cmq non era un problema di variabili passate per valore o per
riferimento perchè il problema ce l'avevo lo stesso.
Come il post di corrado mi ha fatto capire il problema era che subito
dopo l'evento keydown veniva eseguito il keypress che quindi faceva
l'azione standard del tasto back space.
Quindi all'interno della keypress bastava mettere e.handled=true e ora
tutto funziona perfettamente (dopo 2 giorni che mi ci impazzivo sopra
e ci avevo quasi rinunciato)
Grazie comunque per il tempo che mi hai dedicato