BillWoodruff
.. правка 20 октября 2013 года ...
Резюме:
1. В WinForms, в пользовательских элементов управления: компонент tooltip, который является поставщиком расширитель ... в отличие от других компонентов и элементов управления ... не будет функционировать, если вы измените родительский элемент UserControl на другую форму (однако он будет функционировать, если вы измените родительский элемент UserControl на другой ContainerControl в той же форме). Под "Не функцией" я подразумеваю: всплывающие подсказки, установленные во время разработки на внутренних элементах управления UserControl, больше не будут появляться во время выполнения.
2. причины, по которым компонент всплывающей подсказки становится отключенным, если родительский элемент его хостинга UserControl изменяется на другую форму, неясны. Вполне возможно, что это влияет на зависимость компонента всплывающей подсказки от его внутренних указателей на сайт и контейнер.
Как "перенести" всплывающую подсказку в UserControl, если родительский элемент UserControl изменен на другую форму:
0. в образовательных целях:
а. предположим, что у нас есть приложение WinForm с основной формой, 'MainForm, с двумя панелями на нем, 'panel1, 'panel2
б. приложение имеет UserControl, 'userControl1, который имеет одну кнопку и два текстовых поля на нем, а также имеет компонент всплывающей подсказки, добавленный к нему: button1, textBox1, textBox2, toolTip1.
c. один экземпляр UserControl1, 'userControl1, был перетащен в панель основной формы' panel1.
d. приложение создает другую форму, 'Form1
1. Определите открытый метод в UserControl следующим образом:
public void ChangeParent(Control newParent)
{
// clear the existing ToolTips
toolTip1.RemoveAll();
// remove the UserControl from its current host's ControlCollection
this.Parent.Controls.Remove(this);
// add the UserControl to its new host's ControlsCollection
newParent.Controls.Add(this);
// reset the ToolTip depending on the new host
switch (newParent.Name)
{
case "panel1":
toolTip1.SetToolTip(button1, "button1 in panel1");
toolTip1.SetToolTip(textBox1, "textBox1 in panel1");
toolTip1.SetToolTip(textBox2, "textBox2 in panel1");
break;
case "panel2":
toolTip1.SetToolTip(button1, "button1 in panel2");
toolTip1.SetToolTip(textBox1, "textBox1 in panel2");
toolTip1.SetToolTip(textBox2, "textBox2 in panel2");
break;
case "Form1":
toolTip1.SetToolTip(button1, "button1 in Form1");
toolTip1.SetToolTip(textBox1, "textBox1 in Form1");
toolTip1.SetToolTip(textBox2, "textBox2 in Form1");
break;
}
}
Поскольку всплывающие подсказки для элементов управления в UserControl не создаются во время разработки: вызовите метод ChangeParent в обработчике событий загрузки UserControl, чтобы инициализировать их:
private void UserControl1_Load(object sender, EventArgs e)
{
// assume userControl1's inital Parent is 'panel1
ChangeParent(Parent);
}
Обсуждение:
1. поскольку 'ChangeParent является общедоступным методом, он может быть вызван из любого места, имеющего ссылку на экземпляр UserControl 'userControl1. Таким образом, если вы переместили UserControl в другую форму и хотите затем переместить его обратно в исходную родительскую форму, вторая форма должна иметь указатель на исходную форму или ContainerControl в исходной форме, где они хотели бы повторно разместить UserControl (в данном примере это будет 'panel1 в экземпляре основной формы).
2. Вы можете видеть, что то, что здесь сделано, очень похоже на "взлом": всплывающие подсказки очищаются и восстанавливаются каждый раз, когда изменяется родительский элемент UserControl.
Вывод: используйте на свой страх и риск, этот вид взлома вполне может быть затронут в будущем некоторыми изменениями со стороны MS. И, как я подчеркиваю в первоначальном ответе на эту тему (ниже), я считаю, что "перенос" элементов управления из одного ControlContainer или формы в другую не является хорошей практикой программирования ... в долгосрочной перспективе.
.. конец октября 2013 года ...
В то время как вы открыли себя
мочь удалите элемент управления из формы, а затем добавьте его в коллекцию ControlCollection другой формы, сделайте его видимым и используйте его.
структурный проблему можно с помощью
определенный Компоненты, когда вы "переносите" элементы управления таким образом, и всплывающую подсказку, даже если это не так
появиться в наборе инструментов для Visual Studio
как компонент,
является компонент.
Но, прежде чем говорить об особой природе всплывающей подсказки, я хотел бы сказать, что
Я думаю, что перемещение элементов управления из одного контейнера, формы, UserControl в другой или с одной вкладки на другую и т. д. плохой идея, и, по сути, приведет к проблемам позже.
Если вы хотите добавить новый UserControl в Form3 во время выполнения, с его подсказкой на кнопке, точно так же, как вы настроили UserControl во время разработки: просто создайте новый экземпляр UserControl и добавьте его в форму.
Form3 f3 = new Form3();
UserControl1 newUC1 = new UserControl1();
f3.Controls.Add(newUC1);
// position it, etc.
newUC1.Location = new Point(50,50);
f3.Show();
Если вам действительно нужно изменить во время выполнения различные свойства или поведение элемента управления UserControl, то создайте в нем общедоступные свойства, которые предоставляют доступ к объектам или полям, которыми вам нужно манипулировать:
// note the UserControl 'Load Event will not be called when you instantiate a UserControl in code !
public UserControl1()
{
InitializeComponent();
UCToolTip = toolTip1;
UCButton = button1;
}
public ToolTip UC1ToolTip { get; set; }
public Button UC1Button { get; set; }
Затем вы можете сделать что-то в своем коде, например:
newUC.UCToolTip.SetToolTip(newUC.UCButton, "Papa's got a brand new bag.");
А теперь вот много эзотерических подробностей о компонентах и подсказке:
Компоненты имеют зависимость от специальной системы частных переменных.ComponentModel вы видите в каждом файле Designer.cs: частная система.ComponentModel.Компоненты # то # = значение null; когда элемент управления UserControl, или форма, есть компоненты, помещенные в ней, только то, что переменная инициализирована: это.компоненты = новая система.ComponentModel.Контейнер();
Некоторые компоненты в UserControl, такие как таймер, "переживут" миграцию с одного хост-элемента управления на другой без каких-либо проблем.
Но подсказка-это особый вид компонента, который потенциально расширяет возможности каждого элемента управления в форме и самой формы. "Под капотом" всплывающая подсказка имеет свою собственную коллекцию, ComponentCollection, поддерживаемую в ее контейнере.Поле компонентов. Кроме того, всплывающая подсказка "размещается" в своем контейнере довольно особым образом, причем сам "сайт" является экземпляром интерфейса ISite. Когда всплывающая подсказка инициализируется в классе Designer.cs, вы заметите, что это делается с помощью формы его конструктора, который передает свой хост-элемент управления в переменную IContainer.
Когда вы удалите элемент управления UserControl с подсказкой от той или иной форме, или элемент управления UserControl, в controlcollection с ним появляется всплывающая подсказка "сайт" информация "теряется." Хотя вы можете подумать, что можете восстановить эту информацию, и я попытался сделать это в качестве эксперимента: ну, все, что я могу сказать, это то, что я не могу достичь этого с помощью различных экзотических средств, которые я пробовал. Свойство "контейнер" всплывающей подсказки доступно только для чтения, но вы можете установить свойство "сайт".