Reordenação de controlos dentro de um painel de layout fluxo
-
06-07-2019 - |
Pergunta
Estou tendo problemas usando o FlowLayoutPanel em uma aplicação C # winform. O que tem basicamente é um painel de layout de fluxo que tem 3 seções.
Seção # 1 é um conjunto de 2 controles .. dois controles suspensos, eles estão sempre na mesma ordem, sempre visível em todas as instâncias
Seção # 2 é um conjunto de 5 controles diferentes ... com base em uma série de fatores, um dos 5 controles torna-se visível, todos os outros têm o conjunto propert Visible para false
Seção # 3 é um conjunto de 3 controles .. como Seção # 1 eles estão sempre na mesma ordem e sempre visível.
Então, o que isso resume-se a que a Seção nº 2 é variável, os outros são estáticos.
O problema surge com a Seção # 2 ... quando eu alterar a visibilidade de qualquer um dos controles que parecem bem (IE ... Seção 1, em seguida, Seção 2, em seguida, Seção 3) ... exceto quando eu definir o combobox controlar a ser visível .... nesse caso, e apenas nesse caso .. a ordem se torna (Seção 1, em seguida, Seção 3, em seguida, Seção 2) ... Eu não posso imaginar o que faria com que a ordenação estar fora de sync em apenas nesse caso.
O que eu basicamente fazer no início do meu método é definido todos os controles Visible = false ... então eu definir Seção 1 laço Visible = true ... então através das condições da Seção 2 e definir os controles apropriados = visível verdadeiro e finalmente set Seção 3 controles Visible = true.
Alguém tem alguma experiência com o layout de fluxo de pedidos painel de controle? Eu não consigo descobrir o que está acontecendo para o ComboBox.
Solução
Poderia ser mais fácil de cair outra FlowLayoutPanel em para seção 2, em seguida, solte sua seção 2 controles para isso? Dessa forma, os controles visíveis em seu painel superior nunca mudam e você não terá que se preocupar com a ordenação.
Outras dicas
Dentro FlowLayoutPanel.Controls
é uma função método chamado SetChildIndex(Control c, int index)
que lhe permite definir um objeto para um índice específico.
Desde FlowLayoutPanel usa índices de controle para determinar qual a fim de atraí-los, você pode definir isso a qualquer controle do índice que você está querendo swap com, e ele vai bater esse índice controles por um, e cada um depois disso.
Aqui está trecho do meu blog de reordenação PictureBoxes em um FlowLayoutPanel.
Adicionar um FlowLayoutPanel em um WinForm chamado flowLayoutPanel1
:
public partial class TestForm: Form
{
public TestForm()
{
InitializeComponent();
this.flowLayoutPanel1.AllowDrop = true
}
private void AddImageToBlog(System.Drawing.Image image)
{
PictureBox pbox = new PictureBox();
pbox.SizeMode = PictureBoxSizeMode.Zoom;
pbox.Height = (_picturebox_height * _ScaleFactor);
pbox.Width = (_picturebox_width * _ScaleFactor);
pbox.Visible = true;
pbox.Image = image;
pbox.MouseDown += new MouseEventHandler(pbox_MouseDown);
pbox.DragOver += new DragEventHandler(pbox_DragOver);
pbox.AllowDrop = true;
flpNewBlog.Controls.Add(pbox);
}
void pbox_DragOver(object sender, DragEventArgs e)
{
base.OnDragOver(e);
// is another dragable
if (e.Data.GetData(typeof(PictureBox)) != null)
{
FlowLayoutPanel p = (FlowLayoutPanel)(sender as PictureBox).Parent;
//Current Position
int myIndex = p.Controls.GetChildIndex((sender as PictureBox));
//Dragged to control to location of next picturebox
PictureBox q = (PictureBox) e.Data.GetData(typeof(PictureBox));
p.Controls.SetChildIndex(q, myIndex);
}
}
void pbox_MouseDown(object sender, MouseEventArgs e)
{
base.OnMouseDown(e);
DoDragDrop(sender, DragDropEffects.All);
}
}
Você pode reordenar controles sobre flowpanel, mudando propriedade pai de controles e reatribuição propriedade pai com o fim de que você precisa.
Tente esta solução genérica, onde você pode classificar você controla de acordo com uma propriedade no controle de usuário.
// When adding and removing controls, the order is not kept.
var runsOrderedByStartDate = this.nodesFlowLayoutPanel.Controls.Cast<RunNodeControl>().Select(_ => new { StartDate = _.StartDateTime, RunControl = _ }).OrderBy(_ => _.StartDate).ToList();
// Sets index of controls according to their index in the ordered collection
foreach (var anonKeyValue in runsOrderedByStartDate)
{
this.nodesFlowLayoutPanel.Controls.SetChildIndex(anonKeyValue.RunControl, runsOrderedByStartDate.IndexOf(anonKeyValue));
}
SetChildIndex
não repõe a ordem dos controles no painel FlowLayout. Então, quando nós executamos FlowLayoutPanel.GetNextControl(q, true)
a saída não está correto.
Para ordenação controle básico, a maneira mais simples para controlar a ordem dos controles no FlowLayoutPanel é para definir a propriedade FlowLayoutPanel TabStop para true. Defina os controles tabstop propriedade como True e definir a ordem de tabulação para a ordem na qual deseja que os controles aparecer.