c# - 在 flowLayoutPanel 中重新排列 CustomControl

标签 c# custom-controls tabcontrol flowlayoutpanel

我有多个自定义控件(它是一个下面有标签的按钮)添加到 FLP。我试图通过将一个自定义控件拖到另一个控件上来重新排列添加的自定义控件。在一些帮助下,它可以使用简单的按钮,但不能使用自定义控件。 另一个问题是,如果我使用简单的按钮,仅当 FLP 在表单上时才有效,但如果我将 FLP 放在 tabPage 中的 tabControl 中,则不再有效。 为什么不使用自定义控件以及 FLP 位于 tabControl 中?

这是我到目前为止一直在尝试的:

public partial class test_frm : Form
{

   FlowLayoutPanel flowLayoutPanel1 = new FlowLayoutPanel();
    private List<Control> _items = new List<Control>();

    public test_frm()
    {
        InitializeComponent();
        flowLayoutPanel1.AllowDrop = true;
        tabControl1.AllowDrop = true;
        flowLayoutPanel1.Dock = DockStyle.Fill;
        this.Controls.Add(flowLayoutPanel1);
        tabPage1.Controls.Add(flowLayoutPanel1);
        flowLayoutPanel1.DragEnter += new DragEventHandler(flowLayoutPanel1_DragEnter);
        flowLayoutPanel1.DragDrop += new DragEventHandler(flowLayoutPanel1_DragDrop);

        //add custom controls
        for (int i = 0; i < 10; i++)
        {
            Button button = new Button();
            Label lbl = new Label();
            CustomControl cst = new CustomControl(button, lbl);

            button.Text = "Button " + i.ToString();
            lbl.Text = "lbl " + i.ToString();
            cst.Name = "Button " + i.ToString();
            this._items.Add(cst);
            flowLayoutPanel1.Controls.Add(cst);
            cst.MouseDown += new MouseEventHandler(button_MouseDown);
        }
    }


    void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
    {

        List<Control> controls = new List<Control>(flowLayoutPanel1.Controls.Count); // get a copy of the controls on the FLP

        foreach (Control ctr in flowLayoutPanel1.Controls)
        {
            controls.Add(ctr);
        }

        for (int i = 0; i < controls.Count; i++)
        {
            Point mouse = PointToClient(new Point(e.X, e.Y));
            if (controls[i].Bounds.Contains(mouse.X - flowLayoutPanel1.Left, mouse.Y - flowLayoutPanel1.Top))
            //If the control is dragged to another control inside the FlowLayoutPanel, move the dragged control to that place.
            {
                string name = (string)e.Data.GetData(typeof(string));
                Control drag = flowLayoutPanel1.Controls.Find(name, true)[0];
                Control temp = controls[i];
                controls.RemoveAt(getIndex(drag.Name));
                controls.Insert(i, drag);

                flowLayoutPanel1.Controls.Clear(); //Clear the controls
                for (int j = 0; j < controls.Count; j++)
                {
                    flowLayoutPanel1.Controls.Add(controls[j]); //Readd all the Controls in new order
                }
                break;
            }

        }
    }

    private int getIndex(string name)
    {
        int result = -1;
        for (int i = 0; i < flowLayoutPanel1.Controls.Count; i++)
        {
            if (flowLayoutPanel1.Controls[i].Name == name)
            {
                result = i;
                break;
            }
        }
        return result;
    }

    void flowLayoutPanel1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }


    void button_MouseDown(object sender, MouseEventArgs e)
    {
        (sender as CustomControl).DoDragDrop((sender as CustomControl).Name, DragDropEffects.Copy);

    }
}


public class CustomControl : Control
{
    private Button _button;
    private Label _label;


    public CustomControl(Button button, Label label)
    {
        _button = button;
        _label = label;
        button.Width = 64;
        button.Height = 65;
        button.AutoSize = true;
        label.Width = 65;
        button.FlatStyle = FlatStyle.Flat;
        button.AllowDrop = true;
        //button.Margin = new Padding(15, 15, 15, 15);
        button.BackgroundImageLayout = ImageLayout.Stretch;
        Height = button.Height + label.Height;
        Width = 68;

       // Width = Math.Max(button.Width, label.Width);
        Controls.Add(_button);
        _button.Location = new Point(0, 0);
        Controls.Add(_label);
        _label.Location = new Point(0, button.Height);

    }

最佳答案

工作解决方案:

private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
    Control target = new Control();

    target.Parent = sender as Control;

        if (target != null)
        {
            int targetIndex = FindCSTIndex(target.Parent);
            if (targetIndex != -1)
            {
                string cst_ctrl = typeof(CustomControl).FullName;
                if (e.Data.GetDataPresent(cst_ctrl))

                {
                    Button source = new Button();
                    source.Parent = e.Data.GetData(cst_ctrl) as CustomControl;

                    if (targetIndex != -1)
                        this.flowLayoutPanel1.Controls.SetChildIndex(source.Parent, targetIndex);
                }
            }
        }
    }

private int FindCSTIndex(Control cst_ctr)
{
    for (int i = 0; i < this.flowLayoutPanel1.Controls.Count; i++)
    {    
        CustomControl target = this.flowLayoutPanel1.Controls[i] as CustomControl;

        if (cst_ctr.Parent == target)
            return i;
    }
    return -1;
}

private void OnCstMouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        Control cst = sender as Control;
        cst.DoDragDrop(cst.Parent, DragDropEffects.Move);
    }
}

关于c# - 在 flowLayoutPanel 中重新排列 CustomControl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23488144/

相关文章:

java - 在 netbeans 中检索当前打开的文件或项目的位置

c# - WPF 自定义控件 : DependencyProperty of Collection type

c# - 如何以编程方式将 Tab 添加到 TabControl 中,其中停靠了 ListView 控件?

wpf - TabControl 的每个选项卡上的不同 View /用户控件

wpf - 绑定(bind)到 ObservableCollection MVVM 的 TabControl

c# - 停止 wpf Storyboard 并保留实际值

c# - 为什么集合初始值设定项不能与表达式主体属性一起使用?

c# - 在 asp.net 中使用 C# 在具有其他行的列内创建动态行

c# - Windows服务只执行一次

android - 创建自定义通知,包括编辑文本 android