【问题标题】:How to access a form control for another form?如何访问另一个表单的表单控件?
【发布时间】:2011-06-16 22:00:06
【问题描述】:

我有两个Form 类,其中一个有一个ListBox。我需要一个用于ListBoxSelectedIndex 属性的设置器,我想从第二个Form 调用它。

目前我正在做以下事情:

表格 1

public int MyListBoxSelectedIndex
{
     set { lsbMyList.SelectedIndex = value; }
}

表格 2

private ControlForm mainForm; // form 1

public AddNewObjForm()
{
     InitializeComponent();
     mainForm = new ControlForm();           
}

public void SomeMethod()
{
     mainForm.MyListBoxSelectedIndex = -1;
}

这是最好的方法吗?

【问题讨论】:

标签: c# winforms controls


【解决方案1】:

使它们成为单例并不是一个完全坏主意,但我个人不喜欢那样做。我宁愿将一个引用传递给另一种形式。这是一个例子。

Form1 触发 Form2 打开。 Form2 具有重载的构造函数,它将调用表单作为参数并提供对 Form2 成员的引用。这解决了通信问题。例如,我在 Form1 中将 Label 属性公开为 public,在 Form2 中进行了修改。

通过这种方法,您可以以不同的方式进行沟通。

Download Link for Sample Project

//您的 Form1

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

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 frm = new Form2(this);
        frm.Show();
    }

    public string LabelText
    {
        get { return Lbl.Text; }
        set { Lbl.Text = value; }
    }
}

//您的 Form2

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

    private Form1 mainForm = null;
    public Form2(Form callingForm)
    {
        mainForm = callingForm as Form1; 
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.mainForm.LabelText = txtMessage.Text;
    }
}


(来源:ruchitsurati.net


(来源:ruchitsurati.net

【讨论】:

  • 大家好!应该是“private Form1 mainForm = null;”给你错误,只需将“null”更改为“new mainForm();”为我工作。
【解决方案2】:

像这样访问表单的控件:

formname.controls[Index]

您可以转换为适当的控件类型,例如:

DataGridView dgv = (DataGridView) formname.Controls[Index];

【讨论】:

    【解决方案3】:

    我通常将单例设计模式用于 http://en.wikipedia.org/wiki/Singleton_pattern 这样的事情。我将制作应用程序在单例下运行的主窗体,然后为我想在其他区域触摸的窗体和控件创建访问器。然后其他表单可以获取指向他们想要修改的控件的指针,或者他们想要更改的应用程序主要部分中的数据。

    另一种方法是在不同表单上设置事件以进行通信,并使用主表单作为各种中心,将事件消息从一个表单传递到应用程序中的另一个表单。

    【讨论】:

    • 你为什么不直接使用事件呢?这就是它们的用途,无需紧密耦合的对象之间的通信。
    • @Ed Swangren - 这也是我建议他们的原因。这完全是一种选择,尽管它需要更多的时间来完成每个单独的事件,因为你想添加新的钩子,而单例几乎是一次性的。我个人最喜欢做的事情是将 UI 从应用程序的核心行为中抽象出来。该核心就是单例,并且可以附加事件。那么所有的 UI 都只是核心内数据的一个视图。这使得撤消/重做行为变得更加容易。
    • 我没有看到对撤消重做行为的任何要求,我不同意您暗示设置事件是一项繁重的任务的说法。单例通常是任何问题的糟糕解决方案。我打算列出一些支持论点,我在这里找到了一个很好的列表:blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
    【解决方案4】:

    这很简单,首先您可以像这样访问其他表单: (假设你的另一种形式是Form2

    //in Form 1
    Form2 F2 = new Form2();
    foreach (Control c in F2.Controls)
             if(c.Name == "TextBox1")
                c.Text = "hello from Form1";
    

    就是这样,您只需在Form1 中写入TextBox1Form2

    【讨论】:

    • Form2 F2 = new Form2();这将导致表单的新实例,您可能创建的任何更改都将应用于该新实例,而不是“其他”可见表单。
    【解决方案5】:

    如果ChildForm想访问ParentForm

    ParentForm 实例传递给ChildForm 构造函数。

    public partial class ParentForm: Form
    {
        public ParentForm()
        {
            InitializeComponent();
        }
    
        public string ParentProperty{get;set;}
    
        private void CreateChild()
        {
             var childForm = new ChildForm(this);
             childForm.Show();
        }
    }
    
    public partial class ChildForm : Form
    {
        private ParentForm parentForm;
    
        public ChildForm(ParentForm parent)
        {
            InitializeComponent();
    
            parentForm = parent;
            parentForm.ParentProperty = "Value from Child";
        }   
    }
    

    【讨论】:

      【解决方案6】:

      还有另一种方法,以防您不想像 Joe Dabones 建议的那样循环遍历“ALL”控件。 在 Form2 中创建一个函数,然后从 Form1 中调用它。

      public partial class Form2 : Form
      {
          public Form2()
          {
              InitializeComponent();
          }
      
          public void SetIndex(int value)
          {
              lsbMyList.SelectedIndex = value;
          }
      }
      
      public partial class Form1 : Form
      {
          public Form2 frm;
      
          public Form1()
          {
              InitializeComponent();
          }
      
          private void Form1_Load(object sender, EventArgs e)
          {
              frm=new Form2();
              frm.Show();
          }
      
          private void button1_Click(object sender, EventArgs e)
          {
              frm.SetIndex(Int.Parse(textBox1.Text));
          }
      }
      

      【讨论】:

        【解决方案7】:

        这也是另一个执行“查找和突出显示”的示例。还有第二个表单(模式),它打开并包含一个文本框以输入一些文本,然后我们的程序在 RichTextBox(在调用表单中)中查找并突出显示搜索到的文本。 为了选择调用表单中的RichTextBox元素,我们可以使用.Controls.OfType<T>()方法:

        private void findHltBtn_Click(object sender, EventArgs e)
        {
            var StrBox = _callingForm.Controls.OfType<RichTextBox>().First(ctrl => ctrl.Name == "richTextBox1");
            StrBox.SelectionBackColor = Color.White;
        
            var SearchStr = findTxtBox.Text;
            int SearchStrLoc = StrBox.Find(SearchStr);
        
            StrBox.Select(SearchStrLoc, SearchStr.Length);
            StrBox.SelectionBackColor = Color.Yellow;
        }
        

        同样在同一个类(模态表单)中,要访问调用表单,请使用@CuiousGeek 的答案中提到的技术:

        public partial class FindHltModalForm : Form
        {
                private Form2 _callingForm = null;
                public FindHltModalForm()
            {
                InitializeComponent();
            }
            public FindHltModalForm(Form2 CallingForm)
            {
                _callingForm = CallingForm;
                InitializeComponent();
            }
        //...
        

        【讨论】:

          猜你喜欢
          • 2019-09-23
          • 1970-01-01
          • 2016-05-06
          • 1970-01-01
          • 2012-12-09
          • 1970-01-01
          • 2014-03-01
          • 1970-01-01
          相关资源
          最近更新 更多