通过索引方法切换面板

时间:2013-08-06 16:04:29

标签: c# winforms

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

这是帮助理解

的图像(基本)

basic panel

        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);

3 个答案:

答案 0 :(得分: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);
    }
  }
}

答案 1 :(得分:1)

根据你的图片,你在面板中每行有一个控件。因此,我建议您使用TableLayoutPanel代替FlowLayoutPanel。此外,我还为面板中的项目创建用户控件。例如。它将具有名称PriorityUserControl和四个按钮来增加,减少,最大化,最小化它的'优先级'(我将按钮水平放置以便在屏幕上保存位置):

enter image description here

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

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);  
}

我相信你会自己创造两个处理者。

enter image description here

答案 2 :(得分: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个面板(Panel1Panel2Panel3 ...更好地放置不同的背景颜色)并添加两个按钮(buttonUp和{ {1}})。此代码将使buttonDown上下移动(通过更改其与其他面板的位置)。

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

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