【问题标题】:Get access to parent control from user control - C#从用户控件获取对父控件的访问权限 - C#
【发布时间】:2012-01-11 14:05:26
【问题描述】:

如何在 C# (winform) 中访问用户控件的父控件。我正在使用以下代码,但它不适用于所有类型的控件,例如 ListBox。

Control[] Co = this.TopLevelControl.Controls.Find("label7", true);
Co[0].Text = "HelloText"

实际上,我必须从用户控件添加放置在父“表单”上的列表框中的项目。

【问题讨论】:

    标签: c# winforms user-controls


    【解决方案1】:

    说明

    您可以使用Control.Parent 获取父控件。

    样本

    因此,如果您在表单上放置了一个控件,this.Parent 将是您的表单。

    在你的控制范围内你可以做

    Form parentForm = (this.Parent as Form);
    

    更多信息

    Farid-ur-Rahman 发表评论后更新(他在问这个问题

    我的控件和列表框 (listBox1) 都放在窗体 (Form1) 上。当用户按下放置在我的控件中的按钮时,我必须在 listBox1 中添加项目。

    您有两种可能的方法来完成这项工作。

    1.使用 `Control.Parent

    样本

    MyUserControl

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.Parent == null || this.Parent.GetType() != typeof(MyForm))
                return;
    
            ListBox listBox = (this.Parent as MyForm).Controls["listBox1"] as ListBox;
            listBox.Items.Add("Test");
        }
    

    2.

    • 将属性public MyForm ParentForm { get; set; } 放到您的UserControl
    • 在表单中设置属性
    • 假设您的 ListBox 被命名为 listBox1,否则请更改名称

    样本

    我的表单

    public partial class MyForm : Form
    {
        public MyForm()
        {
            InitializeComponent();
            this.myUserControl1.ParentForm = this;
        }
    }
    

    MyUserControl

    public partial class MyUserControl : UserControl
    {
        public MyForm ParentForm { get; set; }
    
        public MyUserControl()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            if (ParentForm == null)
                return;
    
            ListBox listBox = (ParentForm.Controls["listBox1"] as ListBox);
            listBox.Items.Add("Test");
    
        }
    }
    

    【讨论】:

    • - 你能给我一个代码示例来在表单的列表框中添加项目吗?
    • 我需要更多信息来提供帮助。您的控件是否放置在表单上并且此表单上是列表框?那么你想添加到父控件上的列表框吗?
    • 我的控件和列表框 (listBox1) 都放在窗体 (Form1) 上。当用户按下放置在我的控件中的按钮时,我必须在 listBox1 中添加项目。
    • 谢谢。它可以进行一些更改,我正在添加到您的答案中
    • UserControl 已经有这样的属性,同名:msdn.microsoft.com/en-us/library/… 我刚刚注意到,当我在自己的班级中声明了一个新属性时,Visual Studio 会发出警告
    【解决方案2】:

    您可以使用Control.Parent 获取控件的父级或使用Control.FindForm 获取第一个父级Form 控件已打开。两者在查找表单方面存在差异,因此可能比另一种更适合使用。:

    控件的 Parent 属性值可能与 Form 不同 由 FindForm 方法返回。例如,如果 RadioButton 控件是 包含在 GroupBox 控件中,并且 GroupBox 位于窗体上, RadioButton 控件的 Parent 是 GroupBox 和 GroupBox 控件的 Parent 是 Form。

    【讨论】:

    • 不是特定于 winforms 的,而是为了解决控件的父级可能不是实际表单本身的问题,即表单上用户控件中的控件,或者甚至更深的嵌套,这样的事情可以帮助取决于性能问题。 EditFormCS 是主页(表单): private void SetParentEditForm() { var c = this.Parent; while (c != null && !(c is EditFormCS)) { c = c.Parent; } ParentEditFormCs = c 作为 EditFormCS; }
    【解决方案3】:

    Control 有一个名为 Parent 的属性,它将赋予父控件。 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.parent.aspx

    例如Control p = this.Parent;

    【讨论】:

      【解决方案4】:

      您可以通过

      获取控件的父级
      myControl.Parent
      

      参见 MSDN: Control.Parent

      【讨论】:

        【解决方案5】:

        获取我使用过的控件的父级的通用方法是:

        public static T GetParentOfType<T>(this Control control)
        {
            const int loopLimit = 100; // could have outside method
            var current = control;
            var i = 0;
        
            do
            {
                current = current.Parent;
        
                if (current == null) throw new Exception("Could not find parent of specified type");
                if (i++ > loopLimit) throw new Exception("Exceeded loop limit");
        
            } while (current.GetType() != typeof(T));
        
            return (T)Convert.ChangeType(current, typeof(T));
        }
        

        它需要一些工作(例如,如果未找到或错误则返回 null)......但希望可以帮助某人。

        用法:

        var parent = currentControl.GetParentOfType<TypeWanted>();
        

        享受吧!

        【讨论】:

        • current.GetType() != typeof(T) 都是昂贵的操作,最好用 'as T' 强制重写并测试无效性。这将需要 'T : class' 通用约束,这没问题。
        • 可能会使用递归和/或扩展方法进一步改进这一点。
        【解决方案6】:

        不理想,但试试这个...

        将用户控件更改为组件类(在代码编辑器中),构建解决方案并删除所有有错误的代码(与用户控件相关但在组件中不可用,因此调试器会抱怨它)

        将用户控件改回用户控件类...

        现在它可以识别名称和父属性,但将组件显示为不可见,因为它不再可设计。

        【讨论】:

          【解决方案7】:

          根据 Ruskins 的回答和 cmets here 我想出了以下(递归)解决方案:

          public static T GetParentOfType<T>(this Control control) where T : class
          {
              if (control?.Parent == null)
                  return null;
          
              if (control.Parent is T parent)
                  return parent;
          
              return GetParentOfType<T>(control.Parent);
          }
          

          【讨论】:

            【解决方案8】:
            ((frmMain)this.Owner).MyListControl.Items.Add("abc");
            

            确保在 MyListControlfrmMainMyListControl 的私有以外的修饰符属性中提供所需的访问级别

            【讨论】:

              【解决方案9】:

              如果您想通过任何子控件获取任何父级,您可以使用此代码, 当您找到 UserControl/Form/Panel 或其他您可以调用函数或 set/get 值时:

              Control myControl= this;
              while (myControl.Parent != null)
              {
              
                  if (myControl.Parent!=null)
                  {
                      myControl = myControl.Parent;
                      if  (myControl.Name== "MyCustomUserControl")
                      {
                          ((MyCustomUserControl)myControl).lblTitle.Text = "FOUND IT";
                      }
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-09-02
                • 1970-01-01
                • 2011-06-29
                • 2021-12-09
                • 2021-06-09
                • 2016-01-17
                • 1970-01-01
                相关资源
                最近更新 更多