如何重新访问之前在子控件中声明的用户控件?

Posted

技术标签:

【中文标题】如何重新访问之前在子控件中声明的用户控件?【英文标题】:How do I re-access the usercontrol that i've been declared before in a child control? 【发布时间】:2015-06-30 23:13:05 【问题描述】:

我想从我的主窗体重新访问我的一些子用户控件。我想访问我从 WatchListUC 声明的对象“watch” watch = new WatchListUC();

我在主窗体的面板上声明了这个用户控件

 private void MyList_Load(object sender, EventArgs e)
    
        LogInScreen screen = new LogInScreen();
        panel2.Controls.Clear();
        panel2.Controls.Add(screen);
        loadDB();
        grid.ContextMenuStrip = OpenDetails;

    

然后在那之后我创建了一个登录名,在那里我可以调用 WatchListUC watch = new WatchListUC();我想稍后再回忆一下

这是登录屏幕上的代码

private void LogIn_Click(object sender, EventArgs e)
    
        SuspendLayout();
        try
        
            mysqlConnection conn = new MySqlConnection(myConnection);
            conn.Open();
            MySqlCommand command = new MySqlCommand("SELECT * FROM maindatabase.users where user=?parameter1 and pass=?parameter2;", conn);
            command.Parameters.AddWithValue("?parameter1", User.Text);
            command.Parameters.AddWithValue("?parameter2", Pass.Text);
            MySqlDataReader reader = command.ExecuteReader();

            int ctr = 0;
            while (reader.Read())
            
                ctr++;
               // controlnum = reader["idnum"].ToString();
                MyList.AccountControlNum = int.Parse(reader["idnum"].ToString());
               // MessageBox.Show(MyList.AccountControlNum.ToString());
            
            if (ctr == 1)
            
                this.Parent.Controls.Remove(this);
                MyList my = MyList.ActiveForm as MyList;
                UserAccount acc = new UserAccount();
                my.panel2.Controls.Add(acc);
                my.label1.Text = reader["user"].ToString()+" 'List";
                WatchListUC watch = new WatchListUC();
                my.panel3.Controls.Clear();
                my.panel3.Controls.Add(watch);
                FinishListUC finish = new FinishListUC();
                my.panel4.Controls.Clear();
                my.panel4.Controls.Add(finish);
              //  MessageBox.Show("Success!");
            
            else
            
                MessageBox.Show("Invalid Username or Password!");
            

            conn.Close();
            ResumeLayout();
        
        catch (Exception ex)
        
            MessageBox.Show("error" + ex);
            ResumeLayout();
        
        ResumeLayout();
    

现在在我的主窗体上,我如何在“insertWL()”方法之后重新访问这里??

void ConfirmedWL()
    
        SuspendLayout();
        try
        
            MySqlConnection conn = new MySqlConnection(myConnection);
            conn.Open();
            MySqlCommand command = new MySqlCommand("SELECT * FROM maindatabase.watchlist where ControlNum=?CN and idnum=?ID;", conn);
            command.Parameters.AddWithValue("?CN", int.Parse(a.ToString()));
            command.Parameters.AddWithValue("?ID", MyList.AccountControlNum);
            MySqlDataReader reader = command.ExecuteReader();

            int ctr = 0;
            while (reader.Read())
            
                ctr++;

            
            if (ctr == 1)
            
                MessageBox.Show("Already Existed!");
            
            else
            
                insertWL();                    
                //WatchListUC watch1 = panel3.Controls.Find("watch", true).DefaultIfEmpty() as WatchListUC;
                //watch1.dvgRefresh();

              //here i want to recall the watch so i can call the method dvgRefresh();
            


            conn.Close();
            ResumeLayout();
        
        catch  
    <br>

我希望有人可以帮助我,这是我的完整代码和屏幕截图 http://www.mediafire.com/download/1l18e6v8158mi16/Help_please.rar

【问题讨论】:

【参考方案1】:

UserControl 是可视对象,可以像任何对象一样使用。

这意味着您可以将它们的引用存储在最适合您的范围内的任何变量中。

在您的示例中,我将在表单级别定义 watch

WatchListUC watch;

那么,在LogIn_Click事件方法中,这样做并没有错:

watch = new WatchListUC();
my.panel3.Controls.Clear();
my.panel3.Controls.Add(watch);

最后,在ConfirmedWL 方法中,只需使用您拥有的watch 实例即可。

...
else

    insertWL();                    
    watch.dvgRefresh();

这种方法的缺点是您必须小心控制生命周期:

如果没有实例化 watch 将是 null,如果您尝试使用它而不在其中添加新控件,这可能会导致 NullReferenceException。 另外,请记住在使用完动态创建的控件时调用.Dispose()。如果您计划在应用程序生命周期中只有一个 WatchListUC 实例,则不需要这样做。

【讨论】:

ahmm 那么我清除用户控件或处理的方法是错误的吗?我的意思是我使用 panel.control.clear 所以我的另一个问题是我真的需要使用 .dispose() 吗?使用这个有什么好处?谢谢你回答我的问题.. 欢迎您!您的方法是正确的 :) 清除容器只需从容器中删除控件,但您的监视控件仍然存在并且可以重用。 Dispose() 将通过清除它使用的内部资源来防止这种情况。仅当您的代码重复创建和删除控件时,使用 Dispose 才有用。否则,如果您在应用程序生命周期内只有一个监视实例,则没有必要。另一个问题很好地解释了这一点:***.com/questions/1969705/… - 祝你好运! 非常感谢您,我从您那里学到了很多东西。我一直在寻找这个月的解决方案啊,但你把我救在那里..谢谢【参考方案2】:

如果我对您的理解正确,您是在主窗体上的面板内创建 WatchListUC (UserControl) 吗?我很困惑的是这个登录代码在哪里?这也在你的主窗体中吗?

Main Form
   | - Panel
        | - WatchListUC

只要您从主窗体内的代码创建 WatchListUC,您所需要做的就是将其保存到方法范围之外的变量中。

【讨论】:

登录位于不同的面板中,所以我有 2 个用于登录的面板和用于监视列表的面板,每个面板都创建自己的用户控制登录屏幕和监视列表,所以你的意思是我必须在外面创建一个 var?作为菜鸟,我该怎么做? 这是我的完整代码和屏幕,如果你能帮我解决这个问题mediafire.com/download/1l18e6v8158mi16/Help_please.rar

以上是关于如何重新访问之前在子控件中声明的用户控件?的主要内容,如果未能解决你的问题,请参考以下文章

如何给用户控件传递参数

如何在网格上动态重新布局用户控件?

如何从后面的用户控件代码访问用户控件所在的主窗口上的网格列

Qt:子窗口中如何获取主窗体ui中的控件

如何从 viewmodel 访问用户控件上的命令

如何访问父类中的标签表单用户控件?