Hola a todos. Ando creando una aplicacion en c#, y quiero mostrar una ventana desde mi aplicacion (como se haria con un messagebox).
El problema esta en que en lugar de una ventana con texto lo que quiero invocar es un grupo de textbox, pero sin que se encuentren dentro de una ventana con bordes, solo los textbox.
La unica solucion que he encontrado es crear un form, definir los bordes y el fondo transparentes, y poner dentro los textbox, pero mi pregunta es si no existe ninguna clase en System.windows.forms en la que se permita mostrar solo controles, sin falta de encontrarse en ventanas.
Espero que la pregunta quede mas o menos clara, que no es nada facil de explicar :huh:
gracias de antemano.
Puedes hacerlo poniendo la propiedad "Transparencykey" al mismo valor que la propiedad "background".
Si, pero me gustaria saber si hay alguna clase derivada o algo, que ya traiga eso implementado por defecto, sin falta de que yo tenga que editar las propiedades
1. ¿Que tipo de proyecto es?.
Un control debe añadirse a un container que pueda albergar controles, por ende no se puede hacer sin una "ventana", Control.ControlCollection Class (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controlcollection%28v=vs.110%29.aspx), al menos, hasta donde yo se.
Puedes heredar la Class ToolStripControlHost (http://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripcontrolhost%28v=vs.110%29.aspx), para mostrar un popup con un control, pero es limitada y tiene sus inconvenientes, no te servirá de mucho.
O puedes heredar un Form, añadirle los controles y hacer el form "transparente".
Te he escrito un ejemplo completo, para un proyecto de tipo WindowsForms, pero no te acostumbres.
PD: Lo escribí en VB.NET, te servirá para orientarte y puedes traducir el código usando cualquier conversor online: http://converter.telerik.com/
Por un lado, la Class que hereda un System.Windows.Form, la cual se puede mejorar, pero es solo un ejemplo (nótese el color Fuchsia, quizas quieras cambiarlo):
EDITO: Funcionalidad extendida para mover los controles al mantener el botón del ratón.
' ***********************************************************************
' Author : Elektro
' Modified : 03-31-2014
' ***********************************************************************
' <copyright file="ControlsForm.vb" company="Elektro Studios">
' Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' *************************************************************************
''' <summary>
''' Class ControlsForm.
''' Invisible Form designed to host Controls.
''' </summary>
Public Class ControlsForm : Inherits Form
#Region " Variables & Properties "
''' <summary>
''' Indicates whether the Form and it's controls are moveable.
''' </summary>
Private _Moveable As Boolean = False
''' <summary>
''' Indicates whether the moveable events are handled
''' </summary>
Private MoveableIsHandled As Boolean = False
''' <summary>
''' Boolean Flag that indicates whether the Form should be moved.
''' </summary>
Private MoveFormFlag As Boolean = False
''' <summary>
''' Indicates the position where to move the form.
''' </summary>
Private MoveFormPosition As Point = Nothing
''' <summary>
''' Gets or sets a value indicating whether this <see cref="ControlsForm"/> and it's controls are movable.
''' </summary>
''' <value><c>true</c> if controls are movable; otherwise, <c>false</c>.</value>
Public Property Moveable As Boolean
Get
Return Me._Moveable
End Get
Set(ByVal value As Boolean)
Me._Moveable = value
Dim Pan As Panel =
(From p As Panel In MyBase.Controls.OfType(Of Panel)()
Where p.Tag = Me.Handle).First
Select Case value
Case True ' Add Moveable Events to EventHandler.
If Not Me.MoveableIsHandled Then ' If not Moveable handlers are already handled then...
For Each c As Control In Pan.Controls
AddHandler c.MouseDown, AddressOf MouseDown
AddHandler c.MouseUp, AddressOf MouseUp
AddHandler c.MouseMove, AddressOf MouseMove
Next c
Me.MoveableIsHandled = True
End If
Case False ' Remove Moveable Events from EventHandler.
If Me.MoveableIsHandled Then ' If Moveable handlers are already handled then...
For Each c As Control In Pan.Controls
RemoveHandler c.MouseDown, AddressOf MouseDown
RemoveHandler c.MouseUp, AddressOf MouseUp
RemoveHandler c.MouseMove, AddressOf MouseMove
Next c
Me.MoveableIsHandled = False
End If
End Select
End Set
End Property
#End Region
#Region " Constructors "
''' <summary>
''' Prevents a default instance of the <see cref="ControlsForm"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="ControlsForm" /> class.
''' Constructor Overload to display a collection of controls.
''' </summary>
''' <param name="Controls">The control array to display in the Formulary.</param>
''' <param name="FormLocation">The default Formulary location.</param>
Public Sub New(ByVal [Controls] As Control(),
Optional ByVal FormLocation As Point = Nothing)
' InitializeComponent call.
MyBase.SuspendLayout()
MyBase.Name = "ControlsForm"
' Adjust Form size.
MyBase.ClientSize = New Size(0, 0)
MyBase.AutoSize = True
MyBase.AutoSizeMode = AutoSizeMode.GrowAndShrink
' Set the Transparency properties.
MyBase.AllowTransparency = True
MyBase.BackColor = Color.Fuchsia
MyBase.TransparencyKey = Color.Fuchsia
MyBase.DoubleBuffered = False
' Is not necessary to display borders, icon, and taskbar, hide them.
MyBase.FormBorderStyle = BorderStyle.None
MyBase.ShowIcon = False
MyBase.ShowInTaskbar = False
' Instance a Panel to add our controls.
Dim Pan As New Panel
With Pan
' Suspend the Panel layout.
Pan.SuspendLayout()
' Set the Panel properties.
.Name = "ControlsForm Panel"
.Tag = Me.Handle
.AutoSize = True
.AutoSizeMode = AutoSizeMode.GrowAndShrink
.BorderStyle = BorderStyle.None
.Dock = DockStyle.Fill
End With
' Add our controls inside the Panel.
Pan.Controls.AddRange(Controls)
' Add the Panel inside the Form.
MyBase.Controls.Add(Pan)
' If custom Form location is set then...
If Not FormLocation.Equals(Nothing) Then
' Set the StartPosition to manual relocation.
MyBase.StartPosition = FormStartPosition.Manual
' Relocate the form.
MyBase.Location = FormLocation
End If
' Resume layouts.
Pan.ResumeLayout(False)
MyBase.ResumeLayout(False)
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="ControlsForm" /> class.
''' Constructor Overload to display a single control.
''' </summary>
''' <param name="Control">The control to display in the Formulary.</param>
''' <param name="FormLocation">The default Formulary location.</param>
Public Sub New(ByVal [Control] As Control,
Optional ByVal FormLocation As Point = Nothing)
Me.New({[Control]}, FormLocation)
End Sub
#End Region
#Region " Event Handlers "
''' <summary>
''' Handles the MouseDown event of the Form and it's controls.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
Private Shadows Sub MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles MyBase.MouseDown
If e.Button = MouseButtons.Left Then
Me.MoveFormFlag = True
Me.Cursor = Cursors.NoMove2D
Me.MoveFormPosition = e.Location
End If
End Sub
''' <summary>
''' Handles the MouseMove event of the Form and it's controls.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
Private Shadows Sub MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles MyBase.MouseMove
If Me.MoveFormFlag Then
Me.Location += (e.Location - Me.MoveFormPosition)
End If
End Sub
''' <summary>
''' Handles the MouseUp event of the Form and it's controls.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
Private Shadows Sub MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles MyBase.MouseUp
If e.Button = MouseButtons.Left Then
Me.MoveFormFlag = False
Me.Cursor = Cursors.Default
End If
End Sub
#End Region
End Class
Por otro lado, la Class de ejemplo de uso:
EDITO: Class actualizada.
Public Class Form1
#Region " Objects "
' Our inherited Form.
Protected WithEvents frm As ControlsForm = Nothing
' Our controls.
Friend WithEvents tb1 As New TextBox With {.Text = "Elektro-Test 1"}
Friend WithEvents tb2 As New TextBox With {.Text = "Elektro-Test 2"}
Friend WithEvents cb1 As New CheckBox With {.Text = "Elektro-Test 3", .FlatStyle = FlatStyle.Flat}
#End Region
#Region " Constructor "
''' <summary>
''' Initializes a new instance of the <see cref="Form1"/> class.
''' </summary>
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Center this form into the screen.
Me.StartPosition = FormStartPosition.CenterScreen
End Sub
#End Region
#Region " Main Button Event Handlers "
''' <summary>
''' Handles the Click event of the ButtonMain control.
''' </summary>
Private Sub ButtonMain_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles ButtonMain.Click
' Set the Control locations.
tb1.Location = New Point(5, 5)
tb2.Location = New Point(tb1.Location.X, tb1.Location.Y + CInt(tb1.Height * 1.5R))
cb1.Location = New Point(tb2.Location.X, tb2.Location.Y + CInt(tb2.Height * 1.5R))
' Instance the Form that will store our controls.
If frm Is Nothing Then
frm = New ControlsForm({tb1, tb2, cb1},
New Point(Me.Bounds.Right, Me.Bounds.Top))
End If
With frm
.Moveable = True ' Set the Controls moveable.
.Show() ' Display the invisible Form.
End With
End Sub
#End Region
#Region " Textbox's Event Handlers "
''' <summary>
''' Handles the TextChanged event of the TextBox controls.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
Friend Sub tb_textchanged(ByVal sender As Object, ByVal e As KeyPressEventArgs) _
Handles tb1.KeyPress, tb2.KeyPress, cb1.KeyPress
' Just a crazy message-box to interacts with the raised event.
MessageBox.Show("No me da la gana que cambies el texto de mis preciosos controles, asi que voy a hacerlos desaparecer!",
"Elektro Is Angry '¬¬",
MessageBoxButtons.OK, MessageBoxIcon.Stop)
e.Handled = True
' Searchs the ControlsForm
Dim f As Form = sender.FindForm
' ...And close it
f.Hide()
' f.Close()
' f.Dispose()
End Sub
#End Region
End Class
...Que produce este resultado, donde lo de la derecha son 3 textboxes en el interior del Form "transparente":
(http://img401.imageshack.us/img401/2904/01ti.jpg)
Saludos
Muchas gracias por la ayuda, un ejemplo de lo que quiero hacer son los cuadros en los que metes las coordenadas en autocad al dibujar figuras.
Finalmente me va a quedar mas simple el codigo inicial que tenia en el que paso el Form como argumento al constructor de la clase que genera los textbox