encontrei um problema na hora de carregar o ListBox sobre os objeto no formulário.
Ex. Se eu colocar ele Dentro de uma tabcontrol ou tableLayoutPanel o listbox não fica sobre os objeto.
Ai tentei alguma abordagem se sucesso.
Quando Consigo colocar o listbox sobre os controles ele fica fora da posição, que ele deveria ficar, que seria logo abaixo do textobox e do button.
vou deixar uma imagem para vocês verem como ele fica.
(Obs. Postei este código no fórum da Microsoft e fui banido do fórum por esta postagem) Decepcionante.
Se alguém puder me ajuda Agradeço.
veja código do controle
Ex. Se eu colocar ele Dentro de uma tabcontrol ou tableLayoutPanel o listbox não fica sobre os objeto.
Ai tentei alguma abordagem se sucesso.
Quando Consigo colocar o listbox sobre os controles ele fica fora da posição, que ele deveria ficar, que seria logo abaixo do textobox e do button.
vou deixar uma imagem para vocês verem como ele fica.
(Obs. Postei este código no fórum da Microsoft e fui banido do fórum por esta postagem) Decepcionante.
Se alguém puder me ajuda Agradeço.
veja código do controle
ControleComboBox:
public partial class ComboBoxNCMD : UserControl
{
private Panel loadingPanel;
private Label loadingLabel;
private Panel comboPanel;
private ListBox listBox;
private Button dropdownButton;
private TextBox textBox;
private bool isDroppedDown = false;
private int borderSize = 5;
private int borderRadius = 15;
// Propriedades para manipular as cores e bordas
public Color BorderColor { get; set; } = Color.FromArgb(138, 43, 226); // Cor roxa para a borda
public Color BackColorCustom { get; set; } = Color.FromArgb(11, 7, 17); // Cor escura de fundo
public Color FundoLista { get; set; } = Color.FromArgb(35, 32, 39); // Cor escura do fundo da lista
public Color TextColor { get; set; } = Color.White; // Cor do texto
public int BorderSize
{
get { return borderSize; }
set { borderSize = value; this.Invalidate(); }
}
public int BorderRadius
{
get { return borderRadius; }
set { borderRadius = value; this.Invalidate(); }
}
// public bool CarregaDadosNoClick { get; set; } = true;
private int TamanhoControle = 30;
private IContainer components;
private string[] items = new string[0];
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public string[] Items
{
get { return items; }
set
{
items = value;
UpdateListBoxItems(); // Atualize o ListBox e o TextBox quando Items é definido
this.Invalidate();
}
}
//private string[] items=null;
//[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
//public string[] Items
//{
// get { return items; }
// set
// {
// items = value;
// }
//}
public ComboBoxNCMD()
{
AdjustHeightToFont();
InitializeComponent();
InitializeCustomComboBox();
InitializeLoadingPanel();
}
private void InitializeComponent()
{
SuspendLayout();
//
// ComboBoxNCMD
//
Name = "ComboBoxNCMD";
ResumeLayout(false);
}
//usando para mostrar a mensagemde aguarde
private void InitializeLoadingPanel()
{
// Inicializa o painel de carregamento
loadingPanel = new Panel
{
Size = new Size(200, 100), // Ajuste o tamanho conforme necessário
Location = new Point(0, 0),
BackColor = Color.FromArgb(0, 0, 0, 0), // Cor de fundo transparente
Dock = DockStyle.Fill, // Preenche todo o espaço do UserControl
Visible = false // Inicialmente invisível
};
// Inicializa o rótulo de carregamento
loadingLabel = new Label
{
Text = "Aguarde...",
ForeColor = Color.White,
BackColor = Color.FromArgb(0, 0, 0, 128), // Cor de fundo semi-transparente
TextAlign = ContentAlignment.MiddleCenter,
Dock = DockStyle.Fill // Preenche todo o painel
};
// Adiciona o rótulo ao painel
loadingPanel.Controls.Add(loadingLabel);
// Adiciona o painel ao UserControl
this.Controls.Add(loadingPanel);
this.LostFocus += ComboBoxNCMD_LostFocus;
dropdownButton.LostFocus += ComboBoxNCMD_LostFocus;
textBox.LostFocus += ComboBoxNCMD_LostFocus;
}
private void ComboBoxNCMD_LostFocus(object sender, EventArgs e)
{
if (isDroppedDown)
{
if (listBox.Focused == false)
{
listBox.Visible = false;
isDroppedDown = false;
this.Height = TamanhoControle;
}
}
}
private void ShowLoadingPanel()
{
loadingPanel.Visible = true;
// Caso o painel esteja em cima de outros controles, você pode garantir que ele esteja à frente
loadingPanel.BringToFront();
}
private void HideLoadingPanel()
{
loadingPanel.Visible = false;
}
/// <summary>
/// fin da mensagem de aguarde
/// </summary>
private void InitializeCustomComboBox()
{
// Inicializa o Panel que irá conter o TextBox e o Button
comboPanel = new Panel
{
Width = this.Width - 4, // Ajuste para deixar espaço para a borda
Height = TamanhoControle - 4, // Ajuste para a borda
Location = new Point(2, 2), // Posicionado com espaço para a borda
BackColor = BackColorCustom,
Padding = new Padding(BorderSize)
};
// Inicializa o botão do dropdown
dropdownButton = new Button
{
Width = 30,
Height = TamanhoControle - 4, // Ajuste para a borda
Location = new Point(this.Width - 34, 2), // Ajuste para a borda
FlatStyle = FlatStyle.Flat,
Image = CreateArrowImage(), // Cria um ícone de seta personalizado
BackColor = BackColorCustom,
FlatAppearance = { BorderSize = 0, MouseOverBackColor = Color.Transparent, MouseDownBackColor = Color.Transparent },
TabStop = false,
};
// Inicializa o TextBox (área de texto)
textBox = new TextBox
{
Width = this.Width - 34,
Location = new Point(2, 6),
ReadOnly = false,
BackColor = BackColorCustom,
ForeColor = TextColor,
BorderStyle = BorderStyle.None,
AutoCompleteMode = AutoCompleteMode.SuggestAppend,
AutoCompleteSource = AutoCompleteSource.CustomSource,
};
// Inicializa o ListBox (a lista suspensa)
listBox = new ListBox
{
Visible = false,
Width = this.Width - 4, // Ajuste para a borda
Height = 100,
Location = new Point(2, TamanhoControle + 2), // Ajuste para a borda
BackColor = FundoLista,
ForeColor = TextColor,
BorderStyle = BorderStyle.None,
HorizontalScrollbar = true,
};
// Adiciona eventos
dropdownButton.Click += DropdownButton_Click;
//listBox.SelectedIndexChanged += ListBox_SelectedIndexChanged;
listBox.Click += ListBox_Click;
listBox.KeyDown += ListBox_KeyDown;
textBox.Enter += TextBox_Enter;
textBox.KeyDown += TextBox_KeyDown;
// Adiciona o TextBox e o Button no Panel
comboPanel.Controls.Add(textBox);
comboPanel.Controls.Add(dropdownButton);
this.Controls.Add(listBox);
this.Controls.Add(comboPanel);
ApplyColors();
}
// aqui e para indentificar a saida do controle
// Evento para fechar a lista quando o usuário clicar fora do controle
private void ParentForm_MouseDown(object sender, MouseEventArgs e)
{
if (isDroppedDown && !this.Bounds.Contains(e.Location))
{
listBox.Visible = false;
isDroppedDown = false;
this.Height = TamanhoControle;
}
}
protected override void OnParentChanged(EventArgs e)
{
base.OnParentChanged(e);
if (this.ParentForm != null)
{
this.ParentForm.MouseDown += ParentForm_MouseDown;
}
}
//fim das função de vereficação
private void ListBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
ListBox_Click(listBox, new EventArgs());
}
}
private void ListBox_Click(object sender, EventArgs e)
{
if (listBox.SelectedIndex != -1)
{
textBox.Text = listBox.SelectedItem.ToString();
listBox.Visible = false;
isDroppedDown = false;
this.Height = TamanhoControle;
}
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
if (!isDroppedDown)
{
this.Height = 125;
listBox.Visible = true;
listBox.BringToFront();
isDroppedDown = true;
}
if (listBox.Items.Count > 0)
{
// Seleciona o último item
int ultimoIndice = 0;
listBox.SetSelected(ultimoIndice, true);
// Define o foco no ListBox
listBox.Focus();
}
}
else if (e.KeyCode == Keys.Down)
{
if (!isDroppedDown)
{
this.Height = 125;
listBox.Visible = true;
listBox.BringToFront();
isDroppedDown = true;
}
if (listBox.Items.Count > 0)
{
// Seleciona o último item
int ultimoIndice = listBox.Items.Count - 1;
listBox.SetSelected(ultimoIndice, true);
// Define o foco no ListBox
listBox.Focus();
}
}
}
// Método para ajustar a altura do controle com base na fonte
private void AdjustHeightToFont()
{
int textHeight = TextRenderer.MeasureText("A", this.Font).Height;
this.Height = textHeight + 15;
TamanhoControle = this.Height;
}
private void TextBox_Enter(object sender, EventArgs e)
{
UpdateListBoxItems();
this.Height = TamanhoControle;
}
private void DropdownButton_Click(object sender, EventArgs e)
{
if (!isDroppedDown)
{
ShowListBox();
//this.Height = 125;
//listBox.Visible = true;
//listBox.BringToFront();
isDroppedDown = true;
}
else
{
HideListBox();
//listBox.Visible = false;
isDroppedDown = false;
this.Height = TamanhoControle;
}
//UpdateListBoxItems();
}
private void ShowListBox()
{
if (listBox.Items.Count == 0) return; // Não mostrar se não houver itens
isDroppedDown = true;
// Calcula a posição absoluta em relação ao formulário
Point absoluteLocation = this.Parent.PointToScreen(this.Location);
// Remove o ListBox do controle atual e adiciona ao formulário
Form parentForm = this.FindForm();
if (!parentForm.Controls.Contains(listBox))
{
parentForm.Controls.Add(listBox);
}
// Define a posição e o tamanho do ListBox
listBox.Location = new Point(absoluteLocation.X, absoluteLocation.Y + this.Height);
listBox.Width = this.Width;
listBox.Height = Math.Min(200, listBox.Items.Count * listBox.ItemHeight); // Altura máxima de 200px
listBox.BringToFront();
listBox.Visible = true;
// Adiciona o evento para ocultar o ListBox ao clicar fora dele
parentForm.Click += Form_ClickOutside;
}
private void HideListBox()
{
//listBox.Visible = false;
//isDroppedDown = false;
// Remove o ListBox do controle pai
this.Parent.Controls.Remove(listBox);
// Remove o evento de clique fora quando o ListBox é fechado
this.FindForm().Click -= Form_ClickOutside;
}
private void Form_ClickOutside(object sender, EventArgs e)
{
// Oculta o ListBox quando clicar fora da área dele
if (!listBox.Bounds.Contains(Cursor.Position))
{
HideListBox();
}
}
private void UpdateListBoxItems()
{
ShowLoadingPanel();
listBox.Items.Clear();
textBox.AutoCompleteCustomSource.Clear();
if (items != null)
{
if (items.Length > 0)
{
foreach (var item in items)
{
listBox.Items.Add(item);
textBox.AutoCompleteCustomSource.Add(item);
}
}
}
HideLoadingPanel();
}
private void ListBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox.SelectedIndex != -1)
{
textBox.Text = listBox.SelectedItem.ToString();
listBox.Visible = false;
isDroppedDown = false;
this.Height = TamanhoControle;
}
}
// Método para desenhar as bordas personalizadas
private void PaintBorders(Graphics g, Rectangle rect, Color borderColor)
{
int borderRadius = this.BorderRadius;
int borderSize = this.BorderSize;
using (GraphicsPath path = new GraphicsPath())
using (Pen pen = new Pen(borderColor, borderSize))
{
// Desenhe um retângulo com bordas arredondadas
path.AddArc(rect.X, rect.Y, borderRadius, borderRadius, 180, 90);
path.AddArc(rect.Right - borderRadius, rect.Y, borderRadius, borderRadius, 270, 90);
path.AddArc(rect.Right - borderRadius, rect.Bottom - borderRadius, borderRadius, borderRadius, 0, 90);
path.AddArc(rect.X, rect.Bottom - borderRadius, borderRadius, borderRadius, 90, 90);
path.CloseFigure();
g.DrawPath(pen, path);
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Desenha a borda no Panel
Rectangle panelRect = new Rectangle(comboPanel.Location.X - 2, comboPanel.Location.Y - 2, comboPanel.Width + 4, comboPanel.Height + 4);
PaintBorders(e.Graphics, panelRect, BorderColor);
// Desenha a borda no ListBox se ele estiver visível
if (isDroppedDown)
{
Rectangle listBoxRect = new Rectangle(listBox.Location.X - 2, listBox.Location.Y - 2, listBox.Width + 4, listBox.Height + 4);
PaintBorders(e.Graphics, listBoxRect, BorderColor);
}
PaintRoundedBorders(e.Graphics, panelRect, BorderColor);
}
private void PaintRoundedBorders(Graphics g, Rectangle rect, Color borderColor)
{
int borderRadius = 10; // Ajuste o valor conforme necessário
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(rect.X, rect.Y, borderRadius, borderRadius, 180, 90);
path.AddArc(rect.X + rect.Width - borderRadius, rect.Y, borderRadius, borderRadius, 270, 90);
path.AddArc(rect.X + rect.Width - borderRadius, rect.Y + rect.Height - borderRadius, borderRadius, borderRadius, 0, 90);
path.AddArc(rect.X, rect.Y + rect.Height - borderRadius, borderRadius, borderRadius, 90, 90);
path.CloseFigure();
using (Pen pen = new Pen(borderColor, 2))
{
g.DrawPath(pen, path);
}
}
}
public void ApplyColors()
{
comboPanel.BackColor = BackColorCustom;
listBox.BackColor = FundoLista;
dropdownButton.BackColor = BackColorCustom;
textBox.BackColor = BackColorCustom;
listBox.ForeColor = TextColor;
dropdownButton.ForeColor = TextColor;
textBox.ForeColor = TextColor;
listBox.BringToFront();
PaintBorders(this.CreateGraphics(), this.ClientRectangle, BorderColor);
}
private Image CreateArrowImage()
{
Bitmap arrowImage = new Bitmap(16, 16);
using (Graphics g = Graphics.FromImage(arrowImage))
{
g.Clear(Color.Transparent);
Pen pen = new Pen(Color.FromArgb(138, 43, 226), 2);
g.DrawLine(pen, 4, 6, 8, 10);
g.DrawLine(pen, 8, 10, 12, 6);
}
return arrowImage;
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (textBox != null && dropdownButton != null && listBox != null && comboPanel != null)
{
comboPanel.Width = this.Width - 4;
textBox.Width = this.Width - 34;
dropdownButton.Location = new Point(this.Width - 34, 2);
listBox.Width = this.Width - 4;
}
}
}