Получите элемент управления Windows Forms по имени в C#

Большой вопрос!

нет, Обе формы будут (может быть), GC'd, потому что GC непосредственно не ищет ссылки в других ссылках. Это только ищет то, что называют "Корневыми" ссылками... Это включает ссылочные переменные в стек, (Переменная находится на стеке, фактический объект находится, конечно, на "куче"), ссылочные переменные в регистрах ЦП и ссылочные переменные, которые являются статическими полями в классах...

ко Всем другим ссылочным переменным только получают доступ (и GC'd), если на них сошлются в свойстве одного из "корневых" ссылочных объектов, найденных вышеупомянутым процессом... (или в объекте, на который ссылается ссылка в корневом объекте, и т.д....)

Поэтому, только если на одну из форм ссылаются где-то в другом месте в "корневой" ссылке - Тогда, то обе формы будут безопасны от GC.

только способ, которым я могу думать для "доказывания" его, (не используя утилиты трассировки памяти) состоял бы в том, чтобы создать пару сто тысяч из этих форм, в цикле в методе, тогда, в то время как в методе, посмотрите на объем потребляемой памяти приложения, затем выйдите из метода, назовите GC и посмотрите на место снова.

59
задан Peter Mortensen 22 February 2014 в 19:41
поделиться

8 ответов

Use the Control.ControlCollection.Find method.

Try this:

this.Controls.Find()
113
ответ дан 24 November 2019 в 18:01
поделиться

You can do the following:

private ToolStripMenuItem getToolStripMenuItemByName(string nameParam)
   {
      foreach (Control ctn in this.Controls)
         {
            if (ctn is ToolStripMenuItem)
               {
                   if (ctn.Name = nameParam)
                      {
                         return ctn;
                      }
                }
         }
         return null;
    }
0
ответ дан 24 November 2019 в 18:01
поделиться

Since you're generating them dynamically, keep a map between a string and the menu item, that will allow fast retrieval.

// in class scope
private readonly Dictionary<string, ToolStripMenuItem> _menuItemsByName = new Dictionary<string, ToolStripMenuItem>();

// in your method creating items
ToolStripMenuItem createdItem = ...
_menuItemsByName.Add("<name here>", createdItem);

// to access it
ToolStripMenuItem menuItem = _menuItemsByName["<name here>"];
3
ответ дан 24 November 2019 в 18:01
поделиться
Control GetControlByName(string Name)
{
    foreach(Control c in this.Controls)
        if(c.Name == Name)
            return c;

    return null;
}

Disregard this, I reinvent wheels.

9
ответ дан 24 November 2019 в 18:01
поделиться

Have a look at the ToolStrip.Items collection. It even has a find method available.

0
ответ дан 24 November 2019 в 18:01
поделиться
string name = "the_name_you_know";

Control ctn = this.Controls[name];

ctn.Text = "Example...";
36
ответ дан 24 November 2019 в 18:01
поделиться
this.Controls["name"];

Это фактический код, который выполняется:

public virtual Control this[string key]
{
    get
    {
        if (!string.IsNullOrEmpty(key))
        {
            int index = this.IndexOfKey(key);
            if (this.IsValidIndex(index))
            {
                return this[index];
            }
        }
        return null;
    }
}

vs:

public Control[] Find(string key, bool searchAllChildren)
{
    if (string.IsNullOrEmpty(key))
    {
        throw new ArgumentNullException("key", SR.GetString("FindKeyMayNotBeEmptyOrNull"));
    }
    ArrayList list = this.FindInternal(key, searchAllChildren, this, new ArrayList());
    Control[] array = new Control[list.Count];
    list.CopyTo(array, 0);
    return array;
}

private ArrayList FindInternal(string key, bool searchAllChildren, Control.ControlCollection controlsToLookIn, ArrayList foundControls)
{
    if ((controlsToLookIn == null) || (foundControls == null))
    {
        return null;
    }
    try
    {
        for (int i = 0; i < controlsToLookIn.Count; i++)
        {
            if ((controlsToLookIn[i] != null) && WindowsFormsUtils.SafeCompareStrings(controlsToLookIn[i].Name, key, true))
            {
                foundControls.Add(controlsToLookIn[i]);
            }
        }
        if (!searchAllChildren)
        {
            return foundControls;
        }
        for (int j = 0; j < controlsToLookIn.Count; j++)
        {
            if (((controlsToLookIn[j] != null) && (controlsToLookIn[j].Controls != null)) && (controlsToLookIn[j].Controls.Count > 0))
            {
                foundControls = this.FindInternal(key, searchAllChildren, controlsToLookIn[j].Controls, foundControls);
            }
        }
    }
    catch (Exception exception)
    {
        if (ClientUtils.IsSecurityOrCriticalException(exception))
        {
            throw;
        }
    }
    return foundControls;
}
3
ответ дан 24 November 2019 в 18:01
поделиться

this.Controls.Find (name, searchAllChildren) не находит ToolStripItem, потому что ToolStripItem не является элементом управления

  using SWF = System.Windows.Forms;
  using NUF = NUnit.Framework;
  namespace workshop.findControlTest {
     [NUF.TestFixture]
     public class FormTest {
        [NUF.Test]public void Find_menu() {
           // == prepare ==
           var fileTool = new SWF.ToolStripMenuItem();
           fileTool.Name = "fileTool";
           fileTool.Text = "File";

           var menuStrip = new SWF.MenuStrip();
           menuStrip.Items.Add(fileTool);

           var form = new SWF.Form();
           form.Controls.Add(menuStrip);

           // == execute ==
           var ctrl = form.Controls.Find("fileTool", true);

           // == not found! ==
           NUF.Assert.That(ctrl.Length, NUF.Is.EqualTo(0)); 
        }
     }
  }
4
ответ дан 24 November 2019 в 18:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: