No os perdáis la oportunidad de disfrutar con esta gran aportación para los que nos manejamos en Visual Basic!
Sin duda un gran anuncio!
Pep Lluis,
No os perdáis la oportunidad de disfrutar con esta gran aportación para los que nos manejamos en Visual Basic!
Sin duda un gran anuncio!
Pep Lluis,
Tiempo atrás, se estilaba lo de dar noticias “sin comentarios” “solo con imágenes”. En nuestro sector es imposible… pero lo emulamos con un par de líneas de código.
If MessagesYActualizacionesDeAntivirus = Aburrido.deEllos Then
PerformClick( http://www.microsoft.com/security_Essentials/ )
Erase.deEllos()
End If
Que lo disfrutes:-)
Pep Lluis,
Para algunas aplicaciones que utilizan la versión 3.5 del marco y son reeditadas en Visual Studio 2010, tienen la dificultad de no encontrar la referencia a MSChart (Evidentemente si la aplicación lo estaba utilizando) entonces es cuando surge la pregunta… ¿como puedo incorporarlo si quiero continuar trabajando este proyecto con el framework 3.5 como destino?
Para no entrar en discusiones de los filtros aplicados a las librerías según el marco seleccionado, una de las soluciones es simplemente descargar e instalar el control desde :
http://go.microsoft.com/fwlink/?LinkId=128852
Luego simplemente pulsando F5 tendremos de nuevo la compilación libre de errores sin tener que modificar referencia alguna.
Saludos,
Pep Lluis,
Una de las consultas comúnmente solicitadas a través del Blog, tiene que ver con la actualización de datos de dos tablas relacionadas en una BD de SQL, o sea actualizar una vista maestro-detalle vinculadas a sendas tablas.
Aunque por obvio y sencillo, las explicaciones acostumbran a ser de lo más diversas y finalmente te das cuenta que la mayoría de ejemplos se inician con un «desparrame» de jergas incomprensivas para la mayoría. Me decido postearos el ejemplo más básico posible, para que a partir de este punto podáis hacerlo crecer a vuestra necesidad.
Espero que os sea útil y despeje vuestras jaquecas cuando se trata de lidiar con diversas tablas.
PepLluis,
(Para ejecutar el ejemplo, iniciar Visual Studio y crear un nuevo proyecto ‘Winform’, añadir dos DataGridView y un Button, copiar / pegar codigo y por supuesto F5)
Imports System.Data.SqlClient
Public Class Form1
Private Maestro As SqlDataAdapter
Private Detalle As SqlDataAdapter
Private ConjuntoDeDatos As DataSet
Private Sub Form1_Load() Handles MyBase.Load
Dim miConexion As New SqlConnection("Data Source=.\SQLExpress;Initial Catalog=MaestroDetalle;Integrated Security=True")
Maestro = New SqlDataAdapter("Select * From Maestro", miConexion)
Dim MaestroCmdBuilder As New SqlCommandBuilder(Maestro)
Detalle = New SqlDataAdapter("Select * From Detalle", miConexion)
Dim DetalleCmdBuilder As New SqlCommandBuilder(Detalle)
ConjuntoDeDatos = New DataSet
Maestro.Fill(ConjuntoDeDatos, "Maestro")
Me.DataGridView1.DataSource = ConjuntoDeDatos
Me.DataGridView1.DataMember = "Maestro"
Detalle.Fill(ConjuntoDeDatos, "Detalle")
Me.DataGridView2.DataSource = ConjuntoDeDatos
ConjuntoDeDatos.Relations.Add("Fk", ConjuntoDeDatos.Tables("Maestro").Columns("IdMaestro"),
ConjuntoDeDatos.Tables("Detalle").Columns("IdDetalle"))
Me.DataGridView2.DataMember = "Maestro.Fk"
End Sub
Private Sub Actualizar() Handles Button1.Click
If ConjuntoDeDatos.HasChanges Then
Maestro.Update(ConjuntoDeDatos, "Maestro")
Detalle.Update(ConjuntoDeDatos, "Detalle")
End If
End Sub
End Class
Discutiendo sobre la proliferación de núcleos en los procesadores y como sacarle más provecho, os introduzco a la inicialización de colecciones con ‘Query’s’ en Linq utilizando el pragma ‘asParallel’ de esa forma podemos añadir ese atractivo «Extra» a funciones que normalmente dejan que decir por la falta de agilidad al ejecutarse.
' Ejemplo de inicializacion de Query's paralelas
' En este caso usando una coleccion de respuestas sobre una peticion de ping.
' Pep Lluis 2010
Module Module1
Sub Main()
'Si el sistema dispone de mas de un nucleo
If System.Environment.ProcessorCount > 1 Then
'Definir una lista de IP's... por ejemplo :
Dim Ips = {"localhost", "192.168.1.2", "192.168.1.3"}
'Construccion de la Linq parallel query
Dim PingP = From ip In Ips.AsParallel
Select New System.Net.NetworkInformation.Ping().Send(ip)
Dim asParallel As DateTime = DateTime.Now 'Tomar tiempo de incio proceso
'Procesar las respuestas
ProcessPings(PingP)
'Mostrar el tiempo empleado (Desde el inicio hasta el proceso de respuestas)
Console.WriteLine("Tiempo empleado, usando 'AsParallel' : {0}", DateTime.Now - asParallel)
'Query sin 'asParallel'
Dim PingS = From ip In Ips
Select New System.Net.NetworkInformation.Ping().Send(ip)
Dim noParallel As DateTime = DateTime.Now 'Tomar Tiempo de Inicio
ProcessPings(PingS)
Console.WriteLine("Tiempo Empleado sin Parallel Query : {0}", DateTime.Now - noParallel)
Else
Console.WriteLine("No se puede realizar el test con un solo nucleo.")
End If
Console.ReadLine()
End Sub
'Procesar respuestas
Sub ProcessPings(ByVal Pings)
For Each ping In Pings
Console.WriteLine("{0} : {1}", ping.Status, ping.Address)
Next
End Sub
End Module
Espero vuestas opiniones,
Pep Lluis,
I have this post in English version, no doubt in contact with me if needed.
Debido a la insistencia de algunos lectores de este blog, me complace retomar un antiguo ejemplo donde rellenamos un DGV con los datos de una hoja XLS y posteriormente creamos una BD con la tabla correspondiente y en formato MDB. Por lo tanto seguro que con las nuevas herramientas podremos realizar tareas similares con mucho menos código, por eso matizo que se trata de un ejemplo reanimado de 2005 al 2010 J
Las versiones tanto de la XLS como la MDB corresponden al 97-2003. Para poder ejecutar este ejemplo necesitas crear un nuevo proyecto ‘Winforms’ en VB y simplemente copiar y pegar el código en el ‘form1’.
Tenéis que tener en cuenta para que funcione necesitas guardar tu hoja en la carpeta del proyecto ‘Bin/Debug’ (o reléase) según estés compilando y con el nombre ‘Libro1.xls’.
No dudéis en contactar conmigo para aclarar cualquier duda, además si necesitas el proyecto el completo estaré encantado de facilitártelo (Lo tengo para Visual Studio 2010).
Espero vuestras valoraciones.
Happy reentrada!
Pep Lluis,
' --------------------------------------------------------------------------------------------
' * AVISO IMPORTANTE * Este programa es propiedad (c)2010 Pep Lluis Bano.
' * AVISO IMPORTANTE * Se autoriza su uso, solo con fines formativos.
'
' EL USO DE ESTA APLICACION IMPLICA LA ACEPTACION DE LAS CONDICIONES DE USO QUE SE APLICAN
' AL PROGRAMARIO "Open Source", ESTE PROGRAMA SE PROPORCIONA "COMO ESTA", NO OBLIGANDO AL
' AUTOR A CONTRAER COMPROMISO ALGUNO PARA CON QUIENES LO UTILICEN, ASI COMO DECLINANDO
' CUALQUIER REPONSABILIDAD DIRECTA O INDIRECTA, CONTRAIDA POR LOS MISMOS EN SU UTILIZACION
' FUERA DE LOS PROPOSITOS PARA EL QUE FUE ESCRITO Y DISEÑADO.
'
' CUALQUIER MODIFICACIÓN Y DISTRIBUCION DEL MISMO DEBERA CONTENER Y CITAR SU FUENTE Y ORIGEN.
'
' ASI MISMO EL AUTOR AGRADECERA CUALQUIER COMENTARIO o CORRECCION QUE LOS LECTORES CONSIDEREN
' CONTRIBUYENDO ESTOS ULTIMOS A MEJORAR LA APLICACION CON FINES FORMATIVOS.
' CONSIDEREN ENVIAR SUS COMENTARIOS ulizando la opcion [Contact]
' --------------------------------------------------------------------------------------------
Imports ADOX
Imports System.Data.OleDb
Imports System.Text.RegularExpressions
Public Class Form1
'Definir conexion,adaptador y Dataset
Private MiXlsConexion As OleDbConnection
Private MiXlsAdaptador As OleDbDataAdapter
Private MiXlsDataSet As New DataSet()
Private MiXlsDGV As New DataGridView
Private MiMdbConexion As New OleDbConnection
Private MiMdbAdaptador As New OleDbDataAdapter
Private MiMdbDataSet As New DataSet()
Private Mienlazador As New BindingSource
Private MiMdbDGV As New DataGridView
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
MiMdbConexion.Close()
End Sub
Private Sub Form1_Load() Handles MyBase.Load
Dim MiXlsEtiqueta As New Label
MiXlsEtiqueta.Text = "Contenido de la Hoja Excel"
MiXlsEtiqueta.TextAlign = ContentAlignment.MiddleCenter
MiXlsEtiqueta.BorderStyle = BorderStyle.Fixed3D
MiXlsEtiqueta.BackColor = Color.Green
MiXlsEtiqueta.ForeColor = Color.White
MiXlsEtiqueta.Dock = DockStyle.Top
Dim MiXlsDGBPanel As New Panel
MiXlsDGBPanel.AutoSize = True
MiXlsDGV.Dock = DockStyle.Top
MiXlsDGBPanel.Controls.AddRange(New Control() {MiXlsDGV, MiXlsEtiqueta})
Dim MiMdbEtiqueta As New Label
MiMdbEtiqueta.Text = "Contenido de la BD resultante"
MiMdbEtiqueta.TextAlign = ContentAlignment.MiddleCenter
MiMdbEtiqueta.BorderStyle = BorderStyle.Fixed3D
MiMdbEtiqueta.BackColor = Color.Maroon
MiMdbEtiqueta.ForeColor = Color.White
MiMdbEtiqueta.Dock = DockStyle.Top
Dim MiMdbDGBPanel As New Panel
MiMdbDGBPanel.AutoSize = True
MiMdbDGV.Dock = DockStyle.Top
MiMdbDGBPanel.Controls.AddRange(New Control() {MiMdbDGV, MiMdbEtiqueta})
Dim BotonDeActualizar As New Button
BotonDeActualizar.Dock = DockStyle.Bottom
BotonDeActualizar.Text = "Generar Archivo MDB"
Me.AutoSize = True
Me.Text = "De XLS a MDB"
MiXlsDGBPanel.Dock = DockStyle.Top
MiMdbDGBPanel.Dock = DockStyle.Top
Me.Controls.AddRange(New Control() {MiMdbDGBPanel, MiXlsDGBPanel, BotonDeActualizar})
AddHandler BotonDeActualizar.Click, AddressOf GenerarMdb
LeerXls()
End Sub
Private Sub LeerXls()
'Abrir y llenar el DGV con la hoja de excel
MiXlsConexion = New OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;" + _
"Extended Properties = 'Excel 8.0';" + _
"Data Source=|DataDirectory|\libro1.xls;")
MiXlsAdaptador = New OleDbDataAdapter("SELECT * FROM [Hoja1$]", MiXlsConexion)
MiXlsConexion.Open()
MiXlsAdaptador.Fill(MiXlsDataSet)
MiXlsDGV.DataSource = MiXlsDataSet.Tables(0)
End Sub
Private Sub GenerarMdb()
'Eliminar la BD1 si existe
If My.Computer.FileSystem.FileExists("Bd1.mdb") Then
My.Computer.FileSystem.DeleteFile("Bd1.mdb")
End If
'
Dim Nombrede_MiBd = "Bd1.mdb"
Dim NombreDe_MiTabla = "Detalles"
' Para crear una nueva BD de Access, me viene a la
' memoria la funcion Catalog del ADOX.DLL
Dim Catalogo As New ADOX.Catalog()
Catalogo.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Nombrede_MiBd)
'
' Una vez creado el nuevo catalogo añadiremos
' la tabla utilizando el suministrador OLEDB
MiXlsConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
'
' Obtenendremos el esquema de la nueva BD
MiXlsConexion.Open()
Dim MiEsquema As DataTable = MiXlsConexion.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, _
New Object() {Nothing, Nothing, NombreDe_MiTabla, "Detalles"})
'
' El ultimo paso sera crear la estructura en funcion a las columnas de la hoja
Dim Campos As String = "Create Table [" + NombreDe_MiTabla + "] ("
For Each col As DataGridViewTextBoxColumn In MiXlsDGV.Columns
If Campos.EndsWith(")") Or Campos.EndsWith("Key") Then Campos += ", "
Campos += "[" + Regex.Replace(col.DataPropertyName, " ", "_") + "] Text(50)"
Next
Campos += ")"
Dim MiMandato As New OleDbCommand(Campos, MiXlsConexion)
MiMandato.ExecuteNonQuery()
MiXlsConexion.Close()
'
' Añadir todos las filas como registros a la BD
MiMdbConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
MiMdbAdaptador = New OleDbDataAdapter("SELECT * FROM Detalles", MiMdbConexion)
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiMdbAdaptador)
MiMdbConexion.Open()
MiMdbAdaptador.Fill(MiMdbDataSet)
Dim Registro As DataRow
For Each row As DataGridViewRow In MiXlsDGV.Rows
If row.Index < MiXlsDGV.RowCount - 1 Then
Registro = MiMdbDataSet.Tables(0).NewRow
For Each col As DataGridViewColumn In MiXlsDGV.Columns
'Añadir una entrada por celda
Registro(col.Index) = row.Cells(col.Index).Value
Next
'Añadir una linea por fila
MiMdbDataSet.Tables(0).Rows.Add(Registro)
End If
Next
MiMdbAdaptador.Update(MiMdbDataSet)
MiMdbDGV.DataSource = MiMdbDataSet.Tables(0)
MiMdbConexion.Close()
End Sub
End Class
Error HTTP 500.21 – Internal error server
Esta es una pregunta .repetida para muchos de los que después de instalar desde cero «Server 2008» agregan el rol de servidor web después de instalar el Framework 4.0 completo. Para solucionar esto simplemente debes ejecutar de nuevo la instalación del framework 4.0 seleccionando la opción de ‘reparar’ y recuerda agregar el rol de «servidor web» antes del framework la próxima vez. |
This is a question asked by people installing a fresh copy of «Server 2008» and adding web server ROL after Framework 4.0 setup. To solve this just run again framework 4.0 using ‘repair’ option, and remember add web server rol before framework the next time 🙂 |
Regards,
PepLluis,
Parece sencillo pero… no esta tan claro. Es evidente que el uso de un simple ‘Parallel.For’ como cualquier otro proceso a través del framework, requiere de un número de recursos para conformar o organizar, planear y finalmente realizar la ejecución, además podemos suponer que este paralelismo se apoya sobre ‘threading’, por lo que debemos entender su aplicación dentro de escenarios donde exista un uso intensivo en la ejecución de tareas especificas y que estas justifiquen el consumo inicial de recursos en términos de rendimiento. Con dichas conjeturas, está claro que un simple ‘for next’ siempre ganara en velocidad a un ‘parallel.for’, si su ejecución se limita a la iteración sobre una simple estructura o lista y bien entendiendo en funciones cuya ejecución se realiza en una sola pasada.
Sin embargo la situación sufre un cambio radical cuando nuestro bucle itera en llamadas a funciones que realizan tareas con cierta carga de proceso.
Sin ninguna otra pretensión me complace compartir con vosotros un punto de entrada para evaluar la conveniencia o no de usar el paralelismo en determinadas tareas. También es evidente que no se trata de una herramienta formal, simplemente pretende ser un punto de entrada para experimentar de forma sencilla y asequible la implementación de escenarios muy básicos.
Esperando vuestras valoraciones, espero que llame vuestra atención y os complazca. Cuidaros Mucho!
Para probar la aplicación, necesitareis tener instalada la versión beta de Visual Studio 2010 y crear un nuevo proyecto ‘Windows Form Application’ deberemos añadir y distribuir en su form1 las siete etiquetas (del Label1 al Label7) correspondientes a la visualización de los datos del proceso, dos ‘NumericUpDown’ para proporcionarle el numero de bucles e iteraciones, un ‘Progressbar’ para comparar tiempos de ejecución y listo … con copiar y pegar el código adjunto, podréis utilizar este “tester” para vuestra primera aplicación en paralelo J
No dudéis en contactar conmigo si necesitáis cualquier aclaración o si necesitáis que os envíe el prototipo para este proyecto. |
This seems clear and simple but… may be need consider some aspects before J
It is evident that the use of simple Parallel.For’ like any other process through framework, requires a minimum number of resources to conform, to organize, to plan and finally to make the execution, in addition we can suppose that this parallelism leans on `threading’, reason why must be applied within scenes where have an intensive use of processes execution or long tasks, at end only this may justify these initial consumption of resources in performance terms.
With these conjectures, it is clear that simple `for next’ always won in speed to `parallel.for’, if their execution are limited to iterate on a simple structure or list, as well understanding this functions inside single flow process and made one to one.
Nevertheless the situation undergoes a radical change when our iteration calls to functions that make tasks with certain load of process.
Without any other pretension it pleases to me to share with you an entry point to evaluate the convenience of using parallelism in certain tasks. Also it is evident that one is not a formal tool, simply tries to be an entry point to start with a reasonable simple form and the implementation of very basic scenes.
Waiting for your evaluation, I hope this short explanation pleases to you. Take care!
Ps: No doubt in contacting with me if you need any extra explanation or if you need that I sent this prototype to you. |
In this sample readings do not seem respond to the real milliseconds, I recommend use `ElapsedTicks’ instead `Elapsed.TotalMilliseconds”, these correspond directly to ticks of chrono, eliminating any other interpretation.
Regards,
Imports System.Threading
‘ Simple Skeleton to test ‘parallel.for’
‘ Pep Lluis 14.07.2009
‘
‘ Compare/test time execution of single over parallel task’s
‘ To run require Visual Studio 2010 Beta
‘ To catch Illegal Cross threat’s exceptions, correct appropriate code
‘ or set false, Checking cross thread calls.
Public Class SingleOrParallel
Dim _timer As New System.Timers.Timer
Private Sub SingleOrParallel_Load() Handles MyBase.Load
AddHandler _timer.Elapsed, AddressOf Testing ‘Run Test every elapsed time
_timer.Interval = 1000 ‘elapsed time to 1s
_timer.Enabled = True ‘run timer
End Sub
Dim Elapsed1, Elapsed2 As Double ‘define elapsed memory’s
Sub Testing()
_timer.Enabled = False ‘Stop timer
Me.Label5.Text = «Running Test»
loops = Me.NumericUpDown1.Value ‘read number of loops
SequentialFor() ‘Call Sequential for
ParallelFor() ‘Call Parallel for
‘
‘ Show results
If Elapsed1 > Elapsed2 Then
Label3.ForeColor = Drawing.Color.Red ‘Parallel won
Label4.ForeColor = Drawing.Color.Green
‘show execution time & differences between parallel & single
Me.ProgressBar1.Value = (Elapsed2 * 100 / Elapsed1)
Label5.Text = «fast « + (100 – Int(Elapsed2 / Elapsed1 * 100)).ToString + «%»
Label6.Text = Elapsed1.ToString ‘Single time
Label7.Text = Elapsed2.ToString ‘Parallel time
Else
Label3.ForeColor = Drawing.Color.Green ‘Single won
Label4.ForeColor = Drawing.Color.Red
Me.ProgressBar1.Value = (Elapsed1 * 100 / Elapsed2)
Label5.Text = «fast « + (100 – Int(Elapsed1 / Elapsed2 * 100)).ToString + «%»
Label6.Text = Elapsed2.ToString ‘Parallel time
Label7.Text = Elapsed1.ToString ‘Single time
End If
‘ put result bottom progressbar value
Label7.Left = (Me.ProgressBar1.Left +
((ProgressBar1.Width / ProgressBar1.Maximum) * ProgressBar1.Value)) –
(Label7.Width / 2)
_timer.Enabled = True ‘start timer to next test
End Sub
Dim loops As Integer
Dim Chrono As New Stopwatch
Sub SequentialFor()
Chrono.Start() ‘Start watch
‘ Conventional for next
For n = 0 To loops
SomeTask()
Next
‘ remember Elapsed time
Elapsed1 = Chrono.Elapsed.TotalMilliseconds
Chrono.Stop() ‘Watch stop
Chrono.Reset() ‘reset!
End Sub
Sub ParallelFor()
Chrono.Start() ‘Start wath
‘ parallel for
Parallel.For(0, loops, Sub(n)
SomeTask()
End Sub)
‘ remember Elapsed time
Elapsed2 = Chrono.Elapsed.TotalMilliseconds
Chrono.Stop() ‘Watch stop
Chrono.Reset() ‘reset!
End Sub
‘
‘Simulated task
Sub SomeTask()
‘Your task here
Thread.SpinWait(NumericUpDown2.Value)
End Sub
End Class
|
|
‘// Utilizar VStudio 2010. ‘// Para entender este ejemplo, imagina que ‘// Este ejemplo además muestra el uso de ‘// Los comentarios y el código están en Ingles |
‘// Test this code with Visual Studio 2010. ‘// To understand this sample… imagine you need ‘// this sample also show how use implicit line |
|
|
Y aqui el Codigo…
‘Define input channel
<FlagsAttribute()> Public Enum InputChannel
PowerAlarm = 1
LowVoltage = 2
HighVoltage = 4
OverCurrent = 8
PowerGood = 16
ShortCircuit = 32
WithoutLoad = 64
OutOfService = 128
End Enum
» Define output channel
<FlagsAttribute()> Public Enum OutputChannel
Engine_Axis1 = 1
Engine_Axis2 = 2
Engine_Axis3 = 4
Smoke_Vent = 8
Refrigerator = 16
Blast_Furnace = 32
TransPort_Belt = 64
Emergency_Stop = 128
End Enum
‘// You can add dynamically items to enum and no changes are needed inside code… just rebuild
‘
Public Class FlagsEnumerationSample
Private Sub When_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
‘Title
Me.Text = «Playing with Flag’s Enum’s»
‘Add all labels and textbox in one shot
Me.Controls.AddRange({New Label With {.Name = «lblHexcaptn»,
.AutoSize = True,
.Location = New Point(5, 10),
.Text = «Output Value:»},
New Label With {.Name = «lblHexValue»,
.AutoSize = True,
.Location = New Point(75, 10),
.Text = «0x00», .Height = 20},
New Label With {.Name = «lblInputVal»,
.AutoSize = True,
.Location = New Point(140, 10),
.Text = «Input Value : 0x»},
New TextBox With {.Name = «txtInputVal»,
.MaxLength = 2,
.Width = 20,
.Location = New Point(220, 8),
.Text = «00»}
})
‘Add one customized button for every item in enumeration
Dim NextPos As Integer = 30 ‘Point for this button (30=initial top pos)
For Each elem In [Enum].GetValues(GetType(OutputChannel)) ‘iterate output enum
Me.Controls.Add(New CustomButton(New Point(20, NextPos), elem)) ‘add new button with new point position for elem
AddHandler Me.Controls(elem.ToString).Click, AddressOf OutPutOnOff ‘When button is click put output on/off
NextPos += Me.Controls(elem.ToString).Height ‘Calculate next point location for next elem
Next
NextPos = 30 ‘Initial top pos for first element
For Each elem In [Enum].GetValues(GetType(InputChannel)) ‘Iterate input enum
Me.Controls.Add(New CustomLabel(New Point(160, NextPos), elem)) ‘Add customized label for any bit input in enum
NextPos += Me.Controls(elem.ToString).Height ‘Calculate location for next label
Next
‘Simulate input value… refresh labels when textbox value change
AddHandler Me.Controls(«txtInputVal»).TextChanged, AddressOf InputsOnOff
Me.Height = NextPos + 50 ‘Fix form height, after last control + 50
End Sub
Private Outputs As Byte = 0 ‘Output channel (Byte)
‘
‘Change On/Off output bit status of sender
‘remark : TAG property of button is used as bit weight
Sub OutPutOnOff(ByVal sender As System.Object, ByVal e As System.EventArgs)
If Outputs And CType(sender, Button).Tag Then ‘Flic /Flac output bit
Outputs = Outputs Xor CType(sender, Button).Tag ‘Set Off if On
sender.BackColor = Color.GreenYellow ‘GreenYellow if Off
Else
Outputs = Outputs Or CType(sender, Button).Tag ‘Set On if Off
sender.BackColor = Color.Red ‘Reed if On
End If
Me.Controls(«lblHexValue»).Text = «0x» + Hex(Outputs)
End Sub
Private Inputs As Byte? = 0 ‘Input channel (Byte)
‘Change color of label when bit is On or Off
‘remark : TAG property of label is used as bit weight
Sub InputsOnOff()
Try
Inputs = «&h0» + Me.Controls(«txtInputVal»).Text ‘Read & convert text as Hex value
Catch ex As Exception
Me.Controls(«txtInputVal»).Text = «» ‘Wrong format… clear textbox
End Try
For Each Elem In [Enum].GetNames(GetType(InputChannel)) ‘for each item in enum
If Inputs And CType(Me.Controls(Elem), Label).Tag Then ‘Red Color if bit is On, Green if off
Me.Controls(Elem).BackColor = Color.Red
Else
Me.Controls(Elem).BackColor = Color.GreenYellow
End If
Next
End Sub
End Class
‘
‘ Just My customizes Button to select and display outputs
Class CustomButton
Inherits Button
‘
‘ Create using
‘ _location inside form
‘ _elem particular item of enumeration
Sub New(ByVal _location As Point, ByVal _elem As [Enum])
Me.Tag = CType(_elem, OutputChannel) ‘My Bit weight
Me.Name = _elem.ToString ‘My Name
Me.Text = Me.Name ‘Name to Show
Me.Width = 100 ‘Wide
Me.Location = _location ‘Set Position
Me.BackColor = Color.GreenYellow ‘Initial Color
End Sub
End Class
‘
‘ Just My customized Label to display Inputs
Class CustomLabel
Inherits Label
‘
‘ Create using
‘ _location pos inside form
‘ _elem particular item of enumeration
Sub New(ByVal _location As Point, ByVal _elem As [Enum])
Me.Tag = CType(_elem, InputChannel) ‘My Bit weight
Me.Name = _elem.ToString ‘My Name
Me.Text = Me.Name ‘Name to Show
Me.Width = 100 ‘Wide
Me.Location = _location ‘Position
Me.TextAlign = ContentAlignment.MiddleCenter ‘Align
Me.BackColor = Color.GreenYellow ‘Initial color
Me.BorderStyle = Windows.Forms.BorderStyle.FixedSingle ‘Set Border
End Sub
End Class
Salud,
Pep Lluis,
Hola a todos,
La presente es para comunicaros que durante este mes, no podre atender demasiado a vuestras consultas y compartir los habituales ‘post’ a los que os tengo acostumbrados, aunque parezca mentira por un problema de conectividad en la ubicación actual, eso que tengo una ADSL de 3Mb 🙂
Espero seais pacientes… y que este inconveniente se solucione y pueda volver a estar compartiendo espacio al 100%.
Mil disculpas,
Pep Lluis,