如何动态添加并从表单中的用户控件中删除用户控件

时间:2015-01-05 06:54:37

标签: c# user-controls

我正在努力添加动态并将用户控件移除到表单中。我有一个表单,在我的表单中,我有一个面板,它有一个静态控件。

我想要实现的是将用户控件添加到面板中。虽然很容易添加,但我知道有更好的方法可以做到这一点。

单击表单中的按钮,将用户控件添加到我的面板。

private void btnadd_Click(object sender, EventArgs e)
{
    UserControl1 usr = new UserControl1

    pnlUI.SuspendLayout();
    pnlUI.Controls.Clear();
    pnlUI.Controls.Add(usr);
    pnlUI.ResumeLayout(false);
}
// This one adds it and clearing the control that was already in the panel of the form.

现在,我在这里堆叠了删除添加的用户控件并尝试再次显示已删除或清除的面板中的控件。

在我的用户控件上,后退按钮上有一个后退按钮我试图处理用户控件。但在此之后,原始控件不再存在,面板已经空了。

有什么建议吗?

6 个答案:

答案 0 :(得分:2)

您可以向表单添加实例变量以跟踪以前的控件。这假设面板中只有一个控件。

在你班上:

private Control _previousPanelContent;

然后在你的方法中:

private void btnadd_Click(object sender, EventArgs e)
{
    UserControl1 usr = new UserControl1();

    pnlUI.SuspendLayout();

    // check if there's already content in the panel, if so, keep a reference.
    if (pnlUI.Controls.Count > 0)
    {
        _previousPanelContent = pnlUI.Controls[0];
        pnlUI.Controls.Clear();
    }

    pnlUI.Controls.Add(usr);

    pnlUI.ResumeLayout(false);
}

然后当你想回去时:

    pnlUI.SuspendLayout();
    pnlUI.Controls.Clear();

    // if the previous content was set, add it back to the panel 
    if (_previousPanelContent != null)
    {
        pnlUI.Controls.Add(_previousPanelContent);
    }

    pnlUI.ResumeLayout(false);

答案 1 :(得分:1)

以上是上述评论中提到的事件方法的一个简单示例。

带有“后退”事件的UserControl:

public partial class UserControl1 : UserControl
{

    public event dlgBack Back;
    private UserControl1 _previous = null;
    public delegate void dlgBack(UserControl1 sender, UserControl1 previous);

    public UserControl1(UserControl1 previous)
    {
        InitializeComponent();
        this._previous = previous;
    }

    private void btnBack_Click(object sender, EventArgs e)
    {
        if (Back != null)
        {
            Back(this, _previous);
        }
    }

}

然后,Form创建UserControl并订阅事件:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        UserControl1 prevUsr = pnlUI.Controls.OfType<UserControl1>().FirstOrDefault();
        UserControl1 usr = new UserControl1(prevUsr);
        usr.Back += usr_Back;
        pnlUI.Controls.Clear();
        pnlUI.Controls.Add(usr);
    }

    void usr_Back(UserControl1 sender, UserControl1 previous)
    {
        pnlUI.Controls.Remove(sender);
        if (previous != null)
        {
            pnlUI.Controls.Add(previous);
        }
    }

}

答案 2 :(得分:1)

您正在声明用户控制内部您的按钮回调函数(回调函数是在事件发生时在运行时调用的函数,例如按钮单击等)。 这意味着保存用户控件的变量在其外部无法访问,因此您无法从另一个回调函数中使用它。

而不是这样做:

private void btnadd_Click(object sender, EventArgs e)
{
    //This is not accessible outside the callback function.
    UserControl1 usr = new UserControl1();

    pnlUI.SuspendLayout();
    pnlUI.Controls.Clear();
    pnlUI.Controls.Add(usr);
    pnlUI.ResumeLayout(false);
}

尝试声明一个包含用户控件的属性,以便在其他地方使用它:

//Declare a private property - you can adjust the access level of course,
//depending on what you need.
//You can even declare a field variable for the same cause,such as
//private UserControl _myUserControl;

//This declaration is in the class body.
private UserControl MyUserControl { get; set; }

//Your addition callback function.
private void btnadd_Click(object sender, EventArgs e)
{
    //The user control is now assigned to the property.
    MyUserControl = new UserControl1();

    pnlUI.SuspendLayout();
    pnlUI.Controls.Clear();
    pnlUI.Controls.Add(MyUserControl);
    pnlUI.ResumeLayout(false);
}

//Your removal callback function.
private void btnremove_Click(object sender, EventArgs e)
{
    //...
    //Use the property value here.
    pnlUI.Controls.Remove(MyUserControl);
    //...
}

答案 3 :(得分:1)

我收集了上面的解决方案(主要是@Idle_Mind中的第一个)我刚添加并调整了一些行;我会用他的句子:


以上是上述评论中提到的事件方法的一个简单示例。

带有“后退”事件的UserControl:

No Change here

public partial class UserControl1 : UserControl
{

    public event dlgBack Back;
    private UserControl1 _previous = null;
    public delegate void dlgBack(UserControl1 sender, UserControl1 previous);

    public UserControl1(UserControl1 previous)
    {
        InitializeComponent();
        this._previous = previous;
    }

    private void btnBack_Click(object sender, EventArgs e)
    {
        if (Back != null)
        {
            Back(this, _previous);
        }
    }

}

然后,Form创建UserControl并订阅事件:

Let take a look at commented lines

public partial class Form1 : Form
{
    //prevUsr  is global instead
    private UserControl1 prevUsr = null;
    public Form1()
    {
        InitializeComponent();
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        //prevUsr is removed from here
        //UserControl1 prevUsr = pnlUI.Controls.OfType<UserControl1>().FirstOrDefault();
        UserControl1 usr = new UserControl1(prevUsr);
        usr.Back += usr_Back;
        pnlUI.Controls.Clear();
        pnlUI.Controls.Add(usr);
        //prevUsr is updated
        prevUsr = usr;
    }

    void usr_Back(UserControl1 sender, UserControl1 previous)
    {
        pnlUI.Controls.Remove(sender);
        //prevUsr is updated
        prevUsr = previous;
        if (previous != null)
        {
            pnlUI.Controls.Add(previous);
        }
    }

}

并且,不要忘记设置btnBack_Click以单击UserControl的后退按钮。

我希望这很有帮助,它在我身边很有效;我可以发送或分享完整的VS项目(VS2012)。

答案 4 :(得分:0)

我希望它适合你,

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private int count = 0;
    private LinkedList<UserControl1> lstControls = new LinkedList<UserControl1>();

    private void btnAdd_Click(object sender, EventArgs e)
    {
        var c = new UserControl1();
        if (pnlUI.Controls.Count > 0)
        {
            lstControls.AddLast(pnlUI.Controls[0] as UserControl1);
            pnlUI.Controls.Clear();
        }
        c.lblTitle.Text = "Control #" + (++count).ToString();
        pnlUI.Controls.Add(c);
    }

    private void btnBack_Click(object sender, EventArgs e)
    {
        if (lstControls.Last != null)
        {
            var lastControl = lstControls.Last.Value;
            pnlUI.Controls.Clear();
            pnlUI.Controls.Add(lastControl);
            lstControls.RemoveLast();
        }
    }
}

答案 5 :(得分:0)

我结合了idle_mind,rdavisau和fabrice的答案。我使用rdavisau代码获取控件和idle_mind用于usercontrol和fabrice中的back事件以便在表单中进行一些修改..我希望我可以将赏金分成三个,所以我把它放在空闲的心中..谢谢所有

我创建了一个类:

 class GetControls
{

    private Control[] cntrl;
    public Control[] Previous
    {
    get
    { 
        return cntrl;
    }
        set
        {
            cntrl = value;
        }
    }

}
我的主表单上的

是修改后的代码。

  GetControls help = new GetControls();
  private void btnpay_Click(object sender, EventArgs e)
    {


        TenderUI usr = new TenderUI(prevUsr);
        usr.Back += usr_Back;

        help.Previous = pnlUI.Controls.OfType<Control>().ToArray(); 

        pnlUI.Controls.Clear();
        pnlUI.Controls.Add(usr);


    }

并检索控件

 void usr_Back(TenderUI sender, TenderUI previous)
    {
        pnlUI.Controls.Remove(sender);

        if (help.Previous != null)
        {
            foreach (Control ctr in help.Previous)
            {
                pnlUI.Controls.Add(ctr);
            }
        }
    }