C#-动态创建控件并访问它们 [英] C# - Creating controls dynamically and accessing them

查看:84
本文介绍了C#-动态创建控件并访问它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用选项卡功能创建一个简单的记事本类型的应用程序.我在运行时创建TabControl,其TabPages和RichTextBoxes.我在类范围内实例化了它们.还有一个名为New的MenuStrip项,单击可以添加更多标签页.

I'm creating a simple notepad type of application with the tab functionality. I'm creating the TabControl, its TabPages and RichTextBoxes at run-time. I have them instantiated at class scope. And there is a MenuStrip item called New, by clicking that you can add more tab pages.

TabControl tbcEditor = new TabControl();
TabPage tbPage = new TabPage();
RichTextBox rtb = new RichTextBox();

private void frmTextEditor_Load(object sender, EventArgs e)
{
     Controls.Add(tbcEditor);
     tbcEditor.Dock = DockStyle.Fill;
     tbcEditor.TabPages.Add(tbPage);
     tbPage.Controls.Add(rtb);
     rtb.Dock = DockStyle.Fill;
}

private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
     //TabPage tbPage = new TabPage();
     //RichTextBox rtb = new RichTextBox();

     tbPage.Controls.Add(rtb);
     rtb.Dock = DockStyle.Fill;
     tbcEditor.TabPages.Add(tbPage);
}

我面临的问题有点难以解释.我会尽力的.加载表单后,一切都会按预期进行. TabControl创建带有添加了RichTextBox的TabPage.但是,如果我单击该新建"按钮来添加另一个页面,它就会变得很笨拙.将创建一个新的TabPage,但不添加RichTextBox.也不会引发任何错误.如果我取消注释这2行(在MenuItem click事件下),这将创建2个TabPage和RichTextBox实例,那么一切都会按我的要求进行.

The problem I'm facing is a bit difficult to explain. I'll try my best. When the form loads, everything works as expected. The TabControl creates with a TabPage with a RichTextBox added. However if I click that New button to add another page, it goes bonkers. A new TabPage gets created but without a RichTextBox added. No errors are thrown either. If I un-comment out those 2 lines(under MenuItem click event), which creates 2 instances of TabPage and RichTextBox, everything works as I want.

现在我的第一个问题是,为什么我必须再次仅创建这两种类型的新实例(TabPage,RichTextBox),而不是TabControl?如您在最后一行中看到的,我可以再次使用tbcEditor.但不是tbPagertb.

Now my first question is why do I have to make new instances of only those 2 types(TabPage, RichTextBox) again but not TabControl? As you can see in the last line, I can use tbcEditor once again. But not tbPage and rtb.

当然,我可以继续在本地声明它们,但是随后又出现了另一个问题.如果我想说,添加复制,粘贴功能,我应该做类似的事情,对吧?

Sure I can go on declaring them again at local scope but another issue arises then. If I want to say, add copy, paste functionality, I should do something like this,right?

Clipboard.SetDataObject(rtb.SelectedText);

但是我无法访问rtb,因为它已声明为本地.

But I can't access rtb since it is declared as local.

我对此感到非常困惑,因此,对于如何克服这两个问题的任何建议和想法,我们将不胜感激.

I'm very baffled by this so any suggestions, ideas on how to overcome these 2 issues would be greatly appreciated.

谢谢.

推荐答案

If I un-comment out those 2 lines(under MenuItem click event), which creates 2 instances of TabPage and RichTextBox, everything works as I want.

取消注释这些行时,将再次将富文本框和选项卡页的相同实例添加到容器面板中,这是没有意义的.而是为每个选项卡页添加新控件. (我希望这是要求)

When you uncomment those lines, you are adding the same instance of the rich textbox and tab page to the container panel again which is meaningless. Instead add new controls foreach tabpage. (I hope thats the requirement)

Now my first question is why do I have to make new instances of only those 2 types(TabPage, RichTextBox) again but not TabControl?

TabControl是具有TabPages作为子控件的父控件.一个TabControl下可以有多个选项卡.因此,除了已添加的tbcEditor之外,您无需创建TabControl.我们不会多次添加容器控件(除非有此要求).我们需要更多表格吗?不,只有一种形式可以保留所有子控件的权利.同样,只有一个TabControl可以容纳一组TabPage.仅当您想要每个新选项卡的子选项卡时才需要更多的TabControl,我想这不是必需的.

TabControl is the parent control which has TabPages as child controls. You can have multiple tabs under one TabControl. So you need not create TabControls other than the tbcEditor you have already added. We do not add container controls more than once (unless its the requirement). Do we need more forms? No, just one form which can hold all the child controls right. Similarly just one TabControl which can hold a collection of TabPages. You would need more TabControls only if you want sub-tabs foreach new tab which I guess is not the requirement..

But I can't access rtb since it is declared as local.

这没什么大不了的.您可以通过两种方式进行操作:

This is no big deal. You can do in two ways:

1)通过循环搜索适当的控件. SelectedTab 属性可以提供所需的内容

1) Search for your appropriate control by looping. The SelectedTab property gives what you want.

 private void someEvent(object sender, EventArgs e)
 {           
        foreach (Control c in tbcEditor.SelectedTab.Controls)
        {
            if (c is RichTextBox)
            {
                Clipboard.SetDataObject(((RichTextBox)c).SelectedText);
                break; //assuming u have just one main rtb there
            }
        }
 }

2)创建时,将每个rtb标记到tabPage,然后可以获取所选选项卡页面的tag元素以获取富文本框.我会选择这种方法.

2) Tag each rtb to the tabPage when you create it, and then you can get the tag element of the selected tab page to get the rich text box. I would go for this approach.

(通常,请对您的代码也进行以下更改):

(In general pls make the following changes too to your code):

 TabControl tbcEditor = new TabControl();

 private void frmTextEditor_Load(object sender, EventArgs e)
 {
      Controls.Add(tbcEditor);
      tbcEditor.Dock = DockStyle.Fill;
      AddMyControlsOnNewTab();
 }

private void AddMyControlsOnNewTab()
{
    TabPage tbPage = new TabPage();
    RichTextBox rtb = new RichTextBox();
    tbPage.Tag = rtb; //just one extra bit of line.

    tbcEditor.TabPages.Add(tbPage);
    tbPage.Controls.Add(rtb);
    rtb.Dock = DockStyle.Fill;
}

private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
    AddMyControlsOnNewTab();
}

现在,您可以这样称呼它:

Now, you can call it like this:

 private void someEvent(object sender, EventArgs e)
 {           
        RichTextBox rtb= (RichTextBox)tbcEditor.SelectedTab.Tag;
        Clipboard.SetDataObject(rtb.SelectedText);
        //or even better in just a line,
        //Clipboard.SetDataObject(((RichTextBox)tbcEditor.SelectedTab.Tag).SelectedText);
 }

您在这里需要考虑的是哪个是您首先获得的控件,哪个是您没有获得的控件.无论如何,您都将获得TabPage,而RichTextBox则不会.因此,您必须将RichTextBox标记为TabPage.从 Tag 是object类型的,因此您必须指定它是哪种对象.最后,此方法的优点是您无需遍历列表,因此其性能更高.并且在TabPage中可以有更多RichTextBoxes(前提是您只想复制一组RichTextBoxes中的文本,每个TabPage中的一组文本).

What you have to consider here is which is the control that you first get and which is the one you do not get. You would get TabPage anyways but not the RichTextBox. So you have to tag RichTextBox to TabPage. You have to cast it since Tag is of type object, so you have to specify which kind of object it is. Finally, this method has the advantage that you need not loop through a list, so its more performant. And that you can have more RichTextBoxes in the TabPage (provided you want to copy text from only one set of RichTextBoxes, one from each TabPage)..

这篇关于C#-动态创建控件并访问它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆