Ivan
2008-02-22 01:02:01 UTC
hola a todos,
es mi primera entrada en este grupo como 'escribiente' y [casi] también mis primeras pruebas con vb.net (lo poco que se
es vba, y, por 'simbiosis', un pelín de vb), así que espero me disculpéis si digo muchas burradas.
la cosa es que estoy intentando crear un control de usuario para contar euros según el tipo de moneda: desde el billete
de 500 (quien los pillara) hasta la moneda de 1 céntimo.
en excel me he creado un control personalizado que en realidad es un frame con +/- los mismos controles o equivalentes
que estoy probando en net y mediante una clase consigo que funcione bastante bien (entre ""). Pero por curiosidad y
buscando la idea de tenerlo disponible realmente como si de un Activex se tratara, con sus propiedades y métodos mínimos
disponibles como un control de msForms o similar, me he liado a intentar aprender un poco de Vb.Net, y aquí me hallo,
mas perdido que ...
el control es un UserControl que contiene 15 'grupos de controles' de esta forma =>
.- 1 label para el valor de la moneda (no interviene en nada, es solo informativo)
.- 1 NumberUpDown para introducir o elegir el nº de monedas/billetes. En la prp. Tag almaceno el valor de la moneda
correspondiente( 500, 200, ..., 0.02, 0.01)
.- 1 label que muestra el total por cada moneda
forman dos columnas +/- así => Moneda//NumberUpDown //SubTotal
.-> los NumberUpDown se llaman Num1, Num2, Num3, ....., Num14, Num15
.-> los label para el subtotal se llaman SubT1, .....SubT15, y muestran el resultado de multiplicar el Tag de su
correspondiente NumN con el nº elegido o introducido en este
,- el control se completa con un TextBox para introducir cantidades diversas/aleatorias y otro label (lblTotal) que
muestra la suma total de todos los subtotales mas el textbox (txtOtros)
de momento, y tras unas cuantas peleas con la forma de uso de las funciones intrinsecas de Vb y otras muchas cosas mas,
lo que respecta a los numberupdown, subtotales y total de estos parece funcionar aceptablemente
.->> el problema es el dichoso textbox (curiosamente lo que menos problemas esperaba que me diera)
una vez +/- solucionado el tema de la mascara de entrada (gracias a SoftJaen en un mensaje de este grupo) y a duras
penas los lios con la configuración regional, ahora lo que me ocurre es un sinfín de 'sinsentidos', al menos para mi:
1.-por un lado, no se que evento utilizar para actualizar el total tras los cambios en el textbox: con el TextChanged,
que me parecía lo mas equivalente al change de vba, al intentar ejecutar el control (con F5) me dice algo parecido a
variable de objeto no establecida.
2.- he probado en otros como los de teclado o en Leave, pero lo mas que he conseguido es que en vez de actualizar el
lblTotal ponga en el primer NumberUpDown (Num1) el valor introducido en el Textbox ???, cosa que, o se me esta escapando
algo muy gordo, o no le veo el sentido por ningún lado
bueno, disculpas por el rollo, y aun mas por el código que pongo a continuación, que tampoco es corto, pero si alguno
sabéis/veis donde esta el 'truco' [o metedura de pata] del textbox os lo agradezco
este es el código, de momento, del usercontrol (se llama 'EfectivoCambio')
'****************************************
Public Class EfectivoEuros
Public Valor As Double
Private isDecimal As Boolean
'-------------------
Private Sub Num1_ValueChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Num1.ValueChanged, _
Num2.ValueChanged, Num3.ValueChanged, _
Num4.ValueChanged, Num5.ValueChanged, _
Num6.ValueChanged, Num7.ValueChanged, _
Num8.ValueChanged, Num9.ValueChanged, _
Num10.ValueChanged, Num11.ValueChanged, _
Num12.ValueChanged, Num13.ValueChanged, _
Num14.ValueChanged, Num15.ValueChanged
Calculo(ActiveControl)
End Sub
' -----------------------------
' este proc. y el siguiente en realidad eran solo uno, pero al final lo he dividido intentando
' una solucion con palos de ciego. Tambien he intentado otras cuantas cosillas, pero nada
'
Private Function Calculo(ByRef Ct As Windows.Forms.Control) As Double
Dim Nom As String, lbl As Windows.Forms.Label, _
NumN As Windows.Forms.NumericUpDown
Nom = Microsoft.VisualBasic.Left(Ct.Name, 3)
If Nom = "Num" Then
NumN = Ct
With NumN
lbl = Me.Controls("SubT" & _
Microsoft.VisualBasic.Right(.Name, _
Microsoft.VisualBasic.Len(.Name) - 3))
lbl.Text = Format(.Value * CDbl(.Tag), "0.00")
End With
End If
Valor = Calcular()
End Function
'-----------
Private Function Calcular() As Double
Dim n As Integer, sT As Double, TT As Double
For n = 1 To 15
If Not IsNumeric(Me.Controls("SubT" & n).Text) Then _
Me.Controls("SubT" & n).Text = "0,00"
TT = TT + CDbl(Me.Controls("SubT" & n).Text)
Next
'sT = CDbl(Me.txtOtros.Text)
TT = TT + CDbl(Me.txtOtros.Text) 'sT
lblTotal.Text = Format(TT, "0.00")
End Function
'-------------
Private Sub txtOtros_KeyDown( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs _
) Handles txtOtros.KeyDown
' codigo y comentarios expuestos por SoftJaen en un foro
' junto con el procedimiento 'TeclaPresionada'
'
If e.KeyCode = Windows.Forms.Keys.Decimal Or _
e.KeyCode = Windows.Forms.Keys.Oemcomma Or _
e.KeyCode = Windows.Forms.Keys.OemPeriod Then
' Si se ha pulsado uno de los tres caracteres anteriores, dicho
' carácter actuará como separador decimal del número.
'
isDecimal = True
Else
isDecimal = False
End If
End Sub
'---------------------
Private Sub txtOtros_KeyPress( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyPressEventArgs _
) Handles txtOtros.KeyPress
TeclaPresionada(sender, e, txtOtros, isDecimal)
' este es uno de los intentos
'Calculo(txtOtros)
End Sub
'------------------------
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
End Sub
' --------------------------
' "TeclaPresionada" => codigo y comentarios expuestos
' por SoftJaen en un foro (Gracias de mi parte)
'
Private Sub TeclaPresionada( _
ByRef sender As Object, _
ByRef e As System.Windows.Forms.KeyPressEventArgs, _
ByRef oTextBox As Windows.Forms.TextBox, _
ByVal isDecimal As Boolean)
' Caracter separador decimal existente actualmente
' en la configuración regional de windows.
'
Dim separadorDecimal As String = _
Threading.Thread.CurrentThread. _
CurrentCulture.NumberFormat.NumberDecimalSeparator
If isDecimal Then
' Si en el control hay ya escrito un separador decimal,
' deshechamos insertar otro separador más.
'
If DirectCast(sender, Windows.Forms.TextBox).Text. _
IndexOf(separadorDecimal) >= 0 Then
e.Handled = True
Return
End If
' Insertamos el separador decimal.
'
DirectCast(sender, Windows.Forms.TextBox).SelectedText = separadorDecimal
e.Handled = True
ElseIf Convert.ToInt32(e.KeyChar) = 8 Then
' Se ha pulsado la tecla retroceso
ElseIf e.KeyChar = "-"c Then
' Únicamente si no está seleccionado el texto del control
If oTextBox.SelectionLength = 0 Then
' Solo permito el signo menos si aparece en primera posición
If oTextBox.SelectionStart <> 0 Then e.Handled = True
' Si en el control hay ya escrito un signo menos,
' deshechamos todos los que posteriormente se escriban
If DirectCast(sender, Windows.Forms.TextBox).Text.IndexOf("-") >= 0 Then
e.Handled = True
End If
End If
ElseIf Not (Char.IsDigit(e.KeyChar)) Then
' No se ha pulsado un dígito.
e.Handled = True
End If
End Sub
End Class
'**********************************
si alguno veis donde estoy metiendo la pata os lo agradezco
un saludo
Ivan
es mi primera entrada en este grupo como 'escribiente' y [casi] también mis primeras pruebas con vb.net (lo poco que se
es vba, y, por 'simbiosis', un pelín de vb), así que espero me disculpéis si digo muchas burradas.
la cosa es que estoy intentando crear un control de usuario para contar euros según el tipo de moneda: desde el billete
de 500 (quien los pillara) hasta la moneda de 1 céntimo.
en excel me he creado un control personalizado que en realidad es un frame con +/- los mismos controles o equivalentes
que estoy probando en net y mediante una clase consigo que funcione bastante bien (entre ""). Pero por curiosidad y
buscando la idea de tenerlo disponible realmente como si de un Activex se tratara, con sus propiedades y métodos mínimos
disponibles como un control de msForms o similar, me he liado a intentar aprender un poco de Vb.Net, y aquí me hallo,
mas perdido que ...
el control es un UserControl que contiene 15 'grupos de controles' de esta forma =>
.- 1 label para el valor de la moneda (no interviene en nada, es solo informativo)
.- 1 NumberUpDown para introducir o elegir el nº de monedas/billetes. En la prp. Tag almaceno el valor de la moneda
correspondiente( 500, 200, ..., 0.02, 0.01)
.- 1 label que muestra el total por cada moneda
forman dos columnas +/- así => Moneda//NumberUpDown //SubTotal
.-> los NumberUpDown se llaman Num1, Num2, Num3, ....., Num14, Num15
.-> los label para el subtotal se llaman SubT1, .....SubT15, y muestran el resultado de multiplicar el Tag de su
correspondiente NumN con el nº elegido o introducido en este
,- el control se completa con un TextBox para introducir cantidades diversas/aleatorias y otro label (lblTotal) que
muestra la suma total de todos los subtotales mas el textbox (txtOtros)
de momento, y tras unas cuantas peleas con la forma de uso de las funciones intrinsecas de Vb y otras muchas cosas mas,
lo que respecta a los numberupdown, subtotales y total de estos parece funcionar aceptablemente
.->> el problema es el dichoso textbox (curiosamente lo que menos problemas esperaba que me diera)
una vez +/- solucionado el tema de la mascara de entrada (gracias a SoftJaen en un mensaje de este grupo) y a duras
penas los lios con la configuración regional, ahora lo que me ocurre es un sinfín de 'sinsentidos', al menos para mi:
1.-por un lado, no se que evento utilizar para actualizar el total tras los cambios en el textbox: con el TextChanged,
que me parecía lo mas equivalente al change de vba, al intentar ejecutar el control (con F5) me dice algo parecido a
variable de objeto no establecida.
2.- he probado en otros como los de teclado o en Leave, pero lo mas que he conseguido es que en vez de actualizar el
lblTotal ponga en el primer NumberUpDown (Num1) el valor introducido en el Textbox ???, cosa que, o se me esta escapando
algo muy gordo, o no le veo el sentido por ningún lado
bueno, disculpas por el rollo, y aun mas por el código que pongo a continuación, que tampoco es corto, pero si alguno
sabéis/veis donde esta el 'truco' [o metedura de pata] del textbox os lo agradezco
este es el código, de momento, del usercontrol (se llama 'EfectivoCambio')
'****************************************
Public Class EfectivoEuros
Public Valor As Double
Private isDecimal As Boolean
'-------------------
Private Sub Num1_ValueChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Num1.ValueChanged, _
Num2.ValueChanged, Num3.ValueChanged, _
Num4.ValueChanged, Num5.ValueChanged, _
Num6.ValueChanged, Num7.ValueChanged, _
Num8.ValueChanged, Num9.ValueChanged, _
Num10.ValueChanged, Num11.ValueChanged, _
Num12.ValueChanged, Num13.ValueChanged, _
Num14.ValueChanged, Num15.ValueChanged
Calculo(ActiveControl)
End Sub
' -----------------------------
' este proc. y el siguiente en realidad eran solo uno, pero al final lo he dividido intentando
' una solucion con palos de ciego. Tambien he intentado otras cuantas cosillas, pero nada
'
Private Function Calculo(ByRef Ct As Windows.Forms.Control) As Double
Dim Nom As String, lbl As Windows.Forms.Label, _
NumN As Windows.Forms.NumericUpDown
Nom = Microsoft.VisualBasic.Left(Ct.Name, 3)
If Nom = "Num" Then
NumN = Ct
With NumN
lbl = Me.Controls("SubT" & _
Microsoft.VisualBasic.Right(.Name, _
Microsoft.VisualBasic.Len(.Name) - 3))
lbl.Text = Format(.Value * CDbl(.Tag), "0.00")
End With
End If
Valor = Calcular()
End Function
'-----------
Private Function Calcular() As Double
Dim n As Integer, sT As Double, TT As Double
For n = 1 To 15
If Not IsNumeric(Me.Controls("SubT" & n).Text) Then _
Me.Controls("SubT" & n).Text = "0,00"
TT = TT + CDbl(Me.Controls("SubT" & n).Text)
Next
'sT = CDbl(Me.txtOtros.Text)
TT = TT + CDbl(Me.txtOtros.Text) 'sT
lblTotal.Text = Format(TT, "0.00")
End Function
'-------------
Private Sub txtOtros_KeyDown( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs _
) Handles txtOtros.KeyDown
' codigo y comentarios expuestos por SoftJaen en un foro
' junto con el procedimiento 'TeclaPresionada'
'
If e.KeyCode = Windows.Forms.Keys.Decimal Or _
e.KeyCode = Windows.Forms.Keys.Oemcomma Or _
e.KeyCode = Windows.Forms.Keys.OemPeriod Then
' Si se ha pulsado uno de los tres caracteres anteriores, dicho
' carácter actuará como separador decimal del número.
'
isDecimal = True
Else
isDecimal = False
End If
End Sub
'---------------------
Private Sub txtOtros_KeyPress( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyPressEventArgs _
) Handles txtOtros.KeyPress
TeclaPresionada(sender, e, txtOtros, isDecimal)
' este es uno de los intentos
'Calculo(txtOtros)
End Sub
'------------------------
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
End Sub
' --------------------------
' "TeclaPresionada" => codigo y comentarios expuestos
' por SoftJaen en un foro (Gracias de mi parte)
'
Private Sub TeclaPresionada( _
ByRef sender As Object, _
ByRef e As System.Windows.Forms.KeyPressEventArgs, _
ByRef oTextBox As Windows.Forms.TextBox, _
ByVal isDecimal As Boolean)
' Caracter separador decimal existente actualmente
' en la configuración regional de windows.
'
Dim separadorDecimal As String = _
Threading.Thread.CurrentThread. _
CurrentCulture.NumberFormat.NumberDecimalSeparator
If isDecimal Then
' Si en el control hay ya escrito un separador decimal,
' deshechamos insertar otro separador más.
'
If DirectCast(sender, Windows.Forms.TextBox).Text. _
IndexOf(separadorDecimal) >= 0 Then
e.Handled = True
Return
End If
' Insertamos el separador decimal.
'
DirectCast(sender, Windows.Forms.TextBox).SelectedText = separadorDecimal
e.Handled = True
ElseIf Convert.ToInt32(e.KeyChar) = 8 Then
' Se ha pulsado la tecla retroceso
ElseIf e.KeyChar = "-"c Then
' Únicamente si no está seleccionado el texto del control
If oTextBox.SelectionLength = 0 Then
' Solo permito el signo menos si aparece en primera posición
If oTextBox.SelectionStart <> 0 Then e.Handled = True
' Si en el control hay ya escrito un signo menos,
' deshechamos todos los que posteriormente se escriban
If DirectCast(sender, Windows.Forms.TextBox).Text.IndexOf("-") >= 0 Then
e.Handled = True
End If
End If
ElseIf Not (Char.IsDigit(e.KeyChar)) Then
' No se ha pulsado un dígito.
e.Handled = True
End If
End Sub
End Class
'**********************************
si alguno veis donde estoy metiendo la pata os lo agradezco
un saludo
Ivan