1

很长一段时间以来,我一直在尝试解决我的问题,老实说,我一无所获。我想要的是,当用户单击面板上的“顶部”按钮时,它会自动转到顶部(并与那里的那个交换。)当他们单击底部按钮时,它会自动转到底部。我正在手动设置索引面板,但这当然不起作用,因为它只适用于一个面板(我有十个)。非常感谢一些帮助,以找到一种可以将面板发送到堆栈顶部的方法,而不管其位置如何。

这是帮助理解的图像(基本)

基本面板

        Control ctrlToMove = (Control)this.bookControls[bookName];


        int ctrlToMoveIndex = bookPanel.Controls.IndexOf(ctrlToMove);
        int ctrlToSwapIndex = ctrlToMoveIndex - 5;


        Control ctrlToSwap = bookPanel.Controls[ctrlToSwapIndex];


        this.bookPanel.Controls.SetChildIndex(ctrlToMove, ctrlToSwapIndex);
        this.bookPanel.Controls.SetChildIndex(ctrlToSwap, ctrlToMoveIndex);
4

3 回答 3

1

根据您的图片,您在面板中的每一行都有一个控件。因此,我建议您使用TableLayoutPanel而不是FlowLayoutPanel. 另外我会为面板中的项目创建用户控件。例如,它将有名称PriorityUserControl和四个按钮来增加、减少、最大化、最小化它的“优先级”(我水平放置按钮只是为了在屏幕上保存位置):

在此处输入图像描述

接下来,在此用户控件中创建四个事件:

public event EventHandler PriorityMaximized;
public event EventHandler PriorityIncreased;
public event EventHandler PriorityDecreased;
public event EventHandler PriorityMinimized;

并在单击按钮时引发适当的事件:

private void topButton_Click(object sender, EventArgs e)
{
    if (PriorityMaximized != null)
        PriorityMaximized(this, EventArgs.Empty);
}

而已。我们有用户控制,告诉它是否要向上或向下移动。现在将用户控件添加到 TableLayoutPanel(手动或动态)并将这四个事件的相同事件处理程序订阅到所有用户控件。就像是:

// create user control and attach event handlers 
PriorityUserControl control = new PriorityUserControl();
control.PriorityMaximized += priorityUserControl_PriorityMaximized;
control.PriorityMinimized += priorityUserControl_PriorityMinimized;
control.PriorityIncreased += priorityUserControl_PriorityIncreased;
control.PriorityDecreased += priorityUserControl_PriorityDecreased;
// add another row to table
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
panel.RowCount = panel.RowStyles.Count;
// add control table layout panel
panel.Controls.Add(control);
panel.SetRow(control, panel.RowCount - 1);

好的。您现在应该做的就是实现这些事件处理程序。这很简单。例如降低优先级(即向下移动):

private void priorityUserControl_PriorityDecreased(object sender, EventArgs e)
{
    // sender is a control where you clicked Down button
    Control currentControl = (Control)sender;
    // get position in panel
    var position = panel.GetPositionFromControl(currentControl);
    // just to be sure control is not one at the bottom
    if (position.Row == panel.RowCount - 1)
        return;
    // we want to switch with control beneath current        
    Control controlToSwitch = panel.GetControlFromPosition(0, position.Row + 1);
    // move both controls
    panel.SetRow(currentControl, position.Row + 1);
    panel.SetRow(controlToSwitch, position.Row);            
}

现在实现最大化优先级(即移到顶部):

private void priorityUserControl_PriorityMaximized(object sender, EventArgs e)
{
    Control currentControl = (Control)sender;
    var position = panel.GetPositionFromControl(currentControl);

    if (position.Row == 0 || panel.RowCount < 2)
        return;

    Control topControl = panel.GetControlFromPosition(0, 0);
    panel.SetRow(currentControl, 0);
    panel.SetRow(topControl, position.Row);  
}

我相信你会自己创建休息两个处理程序。

在此处输入图像描述

于 2013-08-06T17:24:10.723 回答
1

根据您的绘图,我制作了一个带有按钮的 UserControl:

void uc_ButtonClicked(object sender, EventArgs e) {
  UserControl1 uc = sender as UserControl1;
  if (uc != null) {
    int childIndex = flowLayoutPanel1.Controls.GetChildIndex(uc);
    if (childIndex > 0) {
      UserControl1 ucTop = flowLayoutPanel1.Controls[0] as UserControl1;
      flowLayoutPanel1.Controls.SetChildIndex(uc, 0);
      flowLayoutPanel1.Controls.SetChildIndex(ucTop, childIndex);
    }
  }
}
于 2013-08-06T16:28:09.117 回答
0

您想要的关键是建立一个清晰且可扩展的算法,能够处理Panels. 在这里,您有一个简单的代码,显示了解决此问题的某些方法:

public partial class Form1 : Form
{
    int[] panelLocations;
    Point[] pointLocations;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        panelLocations = new int[5];
        pointLocations = new Point[5];
        panelLocations[1] = 1;
        panelLocations[2] = 2;
        panelLocations[3] = 3;
        pointLocations[1] = new Point(panel1.Left, panel1.Top); 
        pointLocations[2] = new Point(panel2.Left, panel2.Top);
        pointLocations[3] = new Point(panel3.Left, panel3.Top);
    }

    private void relocate(int curPanel, bool goTop)
    {
        int curLoc = panelLocations[curPanel];
        int newLoc = curLoc - 1;
        if (!goTop)
        {
            newLoc = curLoc + 1;
        }

        if (newLoc < 1) newLoc = 3;
        if (newLoc > 3) newLoc = 1;

        if (newLoc != curLoc)
        {
            int otherIndex = Array.IndexOf(panelLocations, newLoc);
            panelLocations[curPanel] = newLoc;
            relocatePanel(curPanel);

            panelLocations[otherIndex] = curLoc;
            relocatePanel(otherIndex);
        }
    }

    private void relocatePanel(int curIndex)
    {
        if (curIndex == 1)
        {
            panel1.Location = pointLocations[panelLocations[1]];
        }
        else if (curIndex == 2)
        {
            panel2.Location = pointLocations[panelLocations[2]];
        }
        else if (curIndex == 3)
        {
            panel3.Location = pointLocations[panelLocations[3]];
        }

    }

    private void buttonTop1_Click(object sender, EventArgs e)
    {
        relocate(1, true);
    }

    private void buttonBottom1_Click(object sender, EventArgs e)
    {
        relocate(1, false);
    }
}

打开一个新项目,添加 3 个面板(Panel1Panel2...Panel3最好放置不同的背景颜色)并包括两个按钮(buttonUpbuttonDown)。此代码将使Panel1上下移动(通过更改其与其他面板的位置)。

这个想法很简单:一开始你将所有面板的位置存储在一个数组中。在另一个数组中,您存储每个面板每次所在的位置(1 是 的原始位置Panel1,等等)。

这是一个非常简单的代码,您可以根据需要对其进行改进和扩展,但这个想法非常可靠,您可以在任何情况下使用它:一组固定位置,面板将通过这些位置移动。

于 2013-08-06T17:07:29.117 回答