elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Como crear un array de controles desde un módulo dentro de un control (Panel)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Como crear un array de controles desde un módulo dentro de un control (Panel)  (Leído 1,614 veces)
Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Como crear un array de controles desde un módulo dentro de un control (Panel)
« en: 22 Septiembre 2015, 19:36 pm »

Hola amigos

Hasta ahora he estado usando Windows Forms, pero para conseguir un aspecto gráfico más bonito en mi aplicación he decidido usar WPF. El problema es que cambian algunos eventos y propiedades y otras cosas y tengo que ir investigando.

Me ha pasado que ya tenía una apliación hecha en Windows Forms y he ido pasado el código a WPF pero resulta que concretamente esto no lo he sabido resolver.

En Windows Forms creé un Panel y un array de controles con Labels. El panel se crea desde un módulo que he llamado (modCrearPanel).  El módulo también tiene eventos y más cosas pero no viene a cuento. La cuestión es poder crear los Labels dentro de un control StackPanel en WPF.


- Primero: Creo un Panel o StackPanel en el Windows Forms y en MainWindow en WPF
- Segundo paso:

EN WINDOWS FORMS
(no es el código original, es una simplificación)
Código
  1. Module Module1
  2.    Dim Etiqueta As New Label
  3.    Dim lblEtiqueta(4) As Label
  4.    Sub CrearPanel()
  5.        Dim Y As Integer = 20
  6.        Dim X As Integer
  7.        Form1.Panel1.BackColor = Color.DarkGray
  8.        X = 10 'valor X inicial
  9.        For I as Integer = 0 To 3
  10.            lblEtiqueta(I) = New Label
  11.            lblEtiqueta(I).Width = 15
  12.            lblEtiqueta(I).Height = 15
  13.            lblEtiqueta(I).BackColor = Color.Gray
  14.            lblEtiqueta(I).Location = New Point(X, Y) 'posición X e Y del cuadro
  15.            Form1.Panel1.Controls.Add(lblEtiqueta(I)) 'Crea el label
  16.            X = X + 20
  17.        Next
  18.    End Sub
  19. End Module
  20.  

CON WPF (NO FUNCIONA)
Código
  1. Module Module1
  2.    Dim Etiqueta As New Label
  3.    Dim lblEtiqueta(4) As Label
  4.    Dim Main As MainWindow
  5.    Public Sub CrearPanel()
  6.        Dim Y As Integer = 10
  7.        Dim X As Integer
  8.        Main.StackPanel1.Background = Brushes.DarkGray
  9.        X = 10
  10.        For i As Integer = 0 To 3
  11.            lblEtiqueta(i) = New Label
  12.            lblEtiqueta(i).Background = Brushes.Gray
  13.            lblEtiqueta(i).Width = 15
  14.            lblEtiqueta(i).Height = 15
  15.            lblEtiqueta(i).Margin = New Thickness(0, X, Y, 0)
  16.            X = X + 20
  17.            Main.StackPanel1.Children.Add(lblEtiqueta(i))
  18.        Next i
  19.        Main.Show()
  20.    End Sub
  21. End Module


Para crear el Penel se llama desde el Load o Loaded en WPF a CrearPanel.

Con toda seguridad el problema está en la forma de poder hacer referencia al StackPanel1 que se encuentra en MainWindow. No se como se hace.


Gracias por ayuda



Encontré la forma   :laugh:


Código
  1. Module Module1
  2.    Dim Etiqueta As New Label
  3.    Dim lblEtiqueta(4) As Label
  4.    Private app As Application
  5.    Private Main As MainWindow
  6.    Public Sub CrearPanel()
  7.        Dim Y As Integer = 10
  8.        Dim X As Integer
  9.        app = System.Windows.Application.Current
  10.        Main = CType(app.MainWindow, MainWindow)
  11.  
  12.        Main.StackPanel1.Background = Brushes.DarkGray
  13.        X = 10
  14.        For i As Integer = 0 To 3
  15.            lblEtiqueta(i) = New Label
  16.            lblEtiqueta(i).Background = Brushes.Gray
  17.            lblEtiqueta(i).Width = 15
  18.            lblEtiqueta(i).Height = 15
  19.            lblEtiqueta(i).Margin = New Thickness(0, X, 0, Y)
  20.            X = X + 20
  21.            Main.StackPanel1.Children.Add(lblEtiqueta(i)) 'Crea el label
  22.        Next i
  23.    End Sub
  24. End Module



Esto es lo que había que añadir al código para poder hacer referencia a objetos creados en MainWindow

Código
  1.    Private app As Application
  2.    Private Main As MainWindow
  3.    Public Sub CrearPanel()
  4.        app = System.Windows.Application.Current
  5.        Main = CType(app.MainWindow, MainWindow)
  6.       Main.StackPanel1.Background = Brushes.DarkGray
  7. End Sub
  8.  

Encontré la solución aquí:
https://msdn.microsoft.com/es-es/library/vstudio/ms750944%28v=vs.100%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Ahora que lo he conseguido hacer solo falta colocar correctamente los labels ya que en susitución a "Location"  he usado "Margin" y no funciona igual. Veré a ver  :-\

Saludos



« Última modificación: 23 Septiembre 2015, 16:09 pm por Lekim » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: Como crear un array de controles desde un módulo dentro de un control (Panel)
« Respuesta #1 en: 22 Septiembre 2015, 20:58 pm »

Respecto al código que has mostrado para WindowsForms, yo evitaría el uso de un módulo en el cual supuestamente defines eventos y los disparas o pones en escucha algún event-handlers despreocupándote de su tiempo de vida, donde además declaras objetos (controles) que probablemente nunca liberarás maunálmente (hasta finalizar la app), pues yo lo haría más o menos así ...dentro de lo que cabe para este ejemplo en particular, en una Class que implementa la interfáz IDisposable:

Código
  1. Public Class TestClass : Implements IDisposable
  2.  
  3.    Private ReadOnly lbl As Label
  4.    Private ReadOnly lblArray(3) As Label
  5.    Private ReadOnly pnl As Panel
  6.  
  7.    <DebuggerStepThrough>
  8.    Public Sub New(ByVal pnl As Panel)
  9.        Me.pnl = pnl
  10.        Me.lbl = New Label
  11.  
  12.        For index As Integer = 0 To (Me.lblArray.Length - 1)
  13.            Me.lblArray(index) = New Label
  14.        Next index
  15.  
  16.        Me.CrearPanel()
  17.    End Sub
  18.  
  19.    Private Sub New()
  20.    End Sub
  21.  
  22.    Private Sub CrearPanel()
  23.  
  24.        Dim startPos As New Point(x:=10, y:=20)
  25.        Dim margin As Integer = 20
  26.  
  27.        Me.pnl.BackColor = Color.DarkGray
  28.  
  29.        For Each lbl As Label In Me.lblArray
  30.  
  31.            With lbl
  32.                .Width = 15
  33.                .Height = 15
  34.                .BackColor = Color.Gray
  35.                .Location = startPos 'posición X e Y del cuadro
  36.                startPos.X += margin
  37.            End With
  38.  
  39.        Next lbl
  40.  
  41.        If Not Me.pnl.InvokeRequired Then
  42.            Me.pnl.Controls.AddRange(Me.lblArray)
  43.        Else
  44.            Me.pnl.Invoke(Sub() Me.pnl.Controls.AddRange(Me.lblArray))
  45.        End If
  46.  
  47.    End Sub
  48.  
  49. #Region "IDisposable Support"
  50.  
  51.    ' To detect redundant calls when disposing.
  52.    Private isDisposed As Boolean = False
  53.  
  54.    ''' <summary>
  55.    ''' Releases all the resources used by this instance.
  56.    ''' </summary>
  57.    Public Sub Dispose() Implements IDisposable.Dispose
  58.        Me.Dispose(isDisposing:=True)
  59.        GC.SuppressFinalize(obj:=Me)
  60.    End Sub
  61.  
  62.    Protected Sub Dispose(ByVal isDisposing As Boolean)
  63.  
  64.        If Not Me.isDisposed Then
  65.  
  66.            If isDisposing Then
  67.  
  68.                ' Dispose managed objects here...
  69.  
  70.                If Me.lbl IsNot Nothing Then
  71.                    Me.lbl.Dispose()
  72.                End If
  73.  
  74.                For Each lbl As Label In Me.lblArray
  75.                    If lbl IsNot Nothing Then
  76.                        lbl.Dispose()
  77.                    End If
  78.                Next lbl
  79.  
  80.            End If
  81.  
  82.        End If
  83.  
  84.        Me.isDisposed = True
  85.  
  86.    End Sub
  87.  
  88. #End Region
  89.  
  90. End Class

Modo de empleo:
Código
  1. Dim cosa As New TestClass(Me.Panel1)
  2. ' cosa.Dispose()



Sobre WPF, asumiré que el control que has elegido cómo equivalente de un panel es un Canvas, en caso contrario hazlo (es lo recomendable por la MSDN).

La respuesta corta es que debes asignar el margen del control con el uso de la propiedad Margin:
Código
  1. Label.Margin = New Thickness(Point.X, Point.Y, 0, 0)

También puedes utilizar las funciones Canvas.SetLeft y Canvas.SetTop para asignar el margen de un control hijo:
Código
  1. Canvas.Children.Add(Label)
  2. Canvas.SetLeft(label, Point.X)
  3. Canvas.SetTop(label, Point.Y)

La respuesta larga es que, si te sientes más agusto con la familiaridad de la tecnología WindowsForms, entonces podrías heredar un label para definir la propiedad personalizada Location y usarla cómo la solias usar antes:

Código
  1. Public Class CustomLabel : Inherits Label
  2.  
  3.    Public Property Location() As Point
  4.        Get
  5.            Return New Point(MyBase.Margin.Left, MyBase.Margin.Top)
  6.        End Get
  7.        Set(ByVal value As Point)
  8.            ' La lógica del método "Set" se podría mejorar para que realmente se pueda considerar un "Location".
  9.            MyBase.Margin = New Thickness(value.X, value.Y, 0, 0)
  10.        End Set
  11.    End Property
  12.  
  13. End Class

Y este código sería el equivalente para WPF de la class de WinForms que mostré arriba, donde aquí como puedes ver no implemento la interfáz IDisposable, ya que a diferencia de WinForms, la mayoría de controles realmente no tienen ningún recurso que liberar.

Código
  1. Public NotInheritable Class TestClass
  2.  
  3.    Private ReadOnly lbl As Label
  4.    Private ReadOnly lblArray(3) As Label
  5.    Private ReadOnly pnl As Canvas
  6.  
  7.    <DebuggerStepThrough>
  8.    Public Sub New(ByVal pnl As Canvas)
  9.        Me.pnl = pnl
  10.        Me.lbl = New Label
  11.  
  12.        For index As Integer = 0 To (Me.lblArray.Length - 1)
  13.            Me.lblArray(index) = New Label
  14.        Next index
  15.  
  16.        Me.CrearPanel()
  17.    End Sub
  18.  
  19.    Private Sub New()
  20.    End Sub
  21.  
  22.    Private Sub CrearPanel()
  23.  
  24.        Dim startPos As New Point(x:=10, y:=20)
  25.        Dim margin As Integer = 20
  26.  
  27.        Me.pnl.Background = Brushes.Gray
  28.  
  29.        For Each lbl As Label In Me.lblArray
  30.  
  31.            With lbl
  32.                .Width = 15
  33.                .Height = 15
  34.                .Background = Brushes.Red
  35.                .Margin = New Thickness(startPos.X, startPos.Y, 0, 0)
  36.  
  37.                startPos.X += margin
  38.            End With
  39.  
  40.            Me.pnl.Children.Add(lbl)
  41.  
  42.        Next lbl
  43.  
  44.    End Sub
  45.  
  46. End Class

Modo de empleo:
Código
  1. Dim cosa As New TestClass(Me.Canvas1)

Saludos


« Última modificación: 22 Septiembre 2015, 21:07 pm por Eleкtro » En línea


Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Como crear un array de controles desde un módulo dentro de un control (Panel)
« Respuesta #2 en: 23 Septiembre 2015, 15:54 pm »

Gracias muy buena respuesta, me has resuelto todas las dudas.;-)

Y lo del canvas es lo que buscaba, creía que el equivalente en WPF era el stackpanel  :P
« Última modificación: 23 Septiembre 2015, 15:56 pm por Lekim » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: Como crear un array de controles desde un módulo dentro de un control (Panel)
« Respuesta #3 en: 23 Septiembre 2015, 16:31 pm »

Y lo del canvas es lo que buscaba, creía que el equivalente en WPF era el stackpanel  :P

Esto te podría servir de ayuda para futuras dudas respecto a otros controles...

Windows Forms Controls and Equivalent WPF Controls - MSDN

Saludos!
En línea


Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Como crear un array de controles desde un módulo dentro de un control (Panel)
« Respuesta #4 en: 23 Septiembre 2015, 17:41 pm »

Ok, gracias Elektro

Por curiosidad he probado de hacer algo parecido con el código que expuse al principio. A ver que te parece  ::)


Código
  1. Module Module1
  2.    Dim lblEtiqueta(4) As Label
  3.    Sub CrearPanel(ByVal pnl As Object, ByVal Disponible As Boolean)
  4.        Dim Starlbl As New Point(x:=10, y:=20)
  5.        pnl.backcolor = Color.DarkGray
  6.        If Disponible Then
  7.  
  8.            For I As Integer = 0 To 3
  9.                lblEtiqueta(I) = New Label
  10.                lblEtiqueta(I).Width = 15
  11.                lblEtiqueta(I).Height = 15
  12.                lblEtiqueta(I).BackColor = Color.Gray
  13.                lblEtiqueta(I).Location = Starlbl 'posición X e Y del cuadro
  14.                pnl.Controls.Add(lblEtiqueta(I)) 'Crea el label
  15.                Starlbl.X += 20
  16.            Next
  17.        Else
  18.            Try
  19.                For Index As Integer = 0 To 3
  20.                    lblEtiqueta(Index).Dispose()
  21.                Next Index
  22.            Catch ex As Exception
  23.            End Try
  24.        End If
  25.    End Sub
  26. End Module
  27.  
  28.  


Para llamar uso:
(para mostrar los Labels)
Código
  1. CrearPanel(Panel1, True)

(para quitar los labels)
Código
  1. CrearPanel(Panel1, False)
« Última modificación: 23 Septiembre 2015, 18:15 pm por Lekim » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines