当控件移动到另一个窗口时,工具提示不会再出现 [英] Tooltip doesn't reappear when control moved to another window

查看:68
本文介绍了当控件移动到另一个窗口时,工具提示不会再出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我希望有人能给我一个提示,为什么我的工具提示只在第一次打开表单时显示。

场景如下:

1.运行应用程序

2.检查是否显示工具提示,接近表单FormWithControl
3.按下按钮打开调用formMiddle.ShowConfigUI(),现在工具提示不再显示。



起始形式为Form4 ,打开formMiddle,它保存UserControl1并将其放入FormWithControl。这里发生的问题是,我有一个带有工具提示的UserControl,UserControl从一个Form移动到另一个Form。然后工具提示不再显示。



我编写了以下内容:

1. UserControl - 一个带有按钮和工具提示的简单用户控件

this.toolTip1.SetToolTip(this.button1,Test button);



2.一个名为FormWithControl的容器表单,显示我的用户控制

  public   partial   class  FormWithControl:Form 
{
MiddleClass _formMiddle;
public FormWithControl(MiddleClass formMiddle)
{
InitializeComponent();
_formMiddle = formMiddle;
}

public void InitalizeShow(UserControl1 usctr)
{
base .Controls.Add(usctr);
}

public void 显示( bool flag)
{
base .Show();
}

private void button1_Click( object sender,EventArgs e)
{
base .Close();
}

private void FormWithControl_FormClosing( object sender,FormClosingEventArgs e)
{
_formMiddle.CloseConfigUI();
}

public void RemoveControls()
{
base .Controls.RemoveAt( 1 );
}
}







3.可能导致开立的控制表表格FormWithControl

  public   partial   class  Form4:Form 
{
MiddleClass formMiddle;

public Form4()
{
InitializeComponent();
formMiddle = new MiddleClass();
formMiddle.InitConfigUI();
}

private void buttonOpen_Click( object sender,EventArgs e)
{
formMiddle.ShowConfigUI();
}
}





4.一个名为MiddleClass的类,代码如下

 public class MiddleClass 
{
FormWithControl formWithControl;
UserControl1 userControl1;

public MiddleClass()
{
userControl1 = new UserControl1();
}

public void InitConfigUI()
{
formWithControl = new FormWithControl(this);
formWithControl.InitalizeShow(userControl1);
formWithControl.Show(true);
}

public void ShowConfigUI()
{
formWithControl = new FormWithControl(this);
formWithControl.InitalizeShow(userControl1);
userControl1.Parent = formWithControl;
formWithControl.Show(true);
userControl1.Focus();
}

public void CloseConfigUI()
{
formWithControl.RemoveControls();
formWithControl.Hide();
}
}

解决方案

...编辑2013年10月20日。 ..



摘要:



1.在WinForms中,在UserControl中: ToolTip组件,它是一个扩展器提供程序......与其他组件和控件...不同,如果您将UserControl的Parent更改为另一个Form,它将无法运行(但是,如果您将UserControl的Parent更改为另一个ContainerControl在同一个Form上。通过不起作用,我的意思是:在UserControl的内部控件上设计时设置的工具提示将不再在运行时出现。



2.原因如果托管UserControl的Parent更改为另一个Form,ToolTip组件似乎被禁用的原因尚不清楚。很可能,ToolTip组件对其Site和Container的内部指针的依赖性会受到影响。



如果UserControl的父级,如何在UserControl中迁移工具提示换成另一种形式:



0.用于教育目的:



a。假设我们有一个WinForm应用程序,主窗体,'MainForm,上面有两个面板',panel1,'panel2



b。该应用程序有一个UserControl,'userControl1,它有一个Button,上面有两个TextBox,并添加了一个ToolTip组件:button1,textBox1,textBox2,toolTip1。



c。 UserControl1的一个实例'userControl1已被拖放到主窗体的'panel1中。



d。该应用程序创建另一个表单,'Form1



1.在UserControl中定义一个公共方法,如下所示:

  public   void  ChangeParent(Control newParent)
{
// 清除现有的工具提示
toolTip1.RemoveAll();

// 从当前主机的ControlCollection中移除UserControl
this .Parent.Controls.Remove( this );

// 将UserControl添加到其新主机的ControlsCollection
newParent.Controls.Add( this );

// 根据新主机重置工具提示
switch (newParent.Name)
{
case panel1
toolTip1.SetToolTip(button1, panel1中的button1);
toolTip1.SetToolTip(textBox1, panel1中的textBox1);
toolTip1.SetToolTip(textBox2, panel1中的textBox2);
break ;
case panel2
toolTip1.SetToolTip(button1, panel2中的button1);
toolTip1.SetToolTip(textBox1, panel2中的textBox1);
toolTip1.SetToolTip(textBox2, panel2中的textBox2);
break ;
case Form1
toolTip1.SetToolTip(button1, Form1中的button1);
toolTip1.SetToolTip(textBox1, Form1中的textBox1);
toolTip1.SetToolTip(textBox2, Form1中的textBox2);
break ;
}
}

由于UserControl中控件的工具提示不是在设计时创建的:在UserControl的'Load EventHandler中调用'ChangeParent方法来初始化它们:< pre lang =cs> private void UserControl1_Load( object sender,EventArgs e)
{
// 假设userControl1的初始父母是' panel1
ChangeParent(Parent);
}

讨论:



1.因为'ChangeParent是一个公共方法,它可以从任何有引用的地方调用到UserControl的userControl1实例。因此,如果您将UserControl移动到另一个Form,并希望将其移回原始的Parent Form,则第二个Form必须有一个指向原始Form的指针,或原始Form上的ContainerControl,他们希望重新生成-site UserControl(在这个例子中,它将是'MainForm实例中的'panel1)。



2.你可以看到这里所做的非常多一个hack:每次更改UserControl的Parent时,ToolTips都会被清除并恢复。



结论:使用这种黑客需要您自担风险通过MS的一些改变,将来很可能会受到影响。并且,正如我在对此主题的原始响应中所强调的那样(下图),我认为从一个ControlContainer或Form中控制控件到另一个不是很好的编程实践......从长远来看。



... 2013年10月结束编辑...



虽然你发现了你可以从表单中删除一个控件,然后将其添加到另一个表单的ControlCollection中,使其可见并使用它,使用<可能存在结构问题当你以这种方式迁移控件时,某些组件和工具提示,即使它出现在Visual Studio 的工具箱中 a组件,组件。



但是,在谈论ToolTip的特殊性之前,我想说我认为将控件从一个容器,Form,UserControl移动到另一个容器,或从一个TabPage移动到另一个TabPage等,是一个非常错误的想法,并且本质上是正在进行的领导 以后的问题。



如果你想在运行时将一个新的UserControl添加到Form3,使用Button上的ToolTip,就像你配置的那样UserControl在设计时:只需创建一个UserControl的新实例并将其添加到Form。

 Form3 f3 = new Form3(); 

UserControl1 newUC1 = new UserControl1();

f3.Controls.Add(newUC1);

//定位等等。
newUC1.Location = new Point(50,50);

f3.Show();

如果你真的需要在运行时修改UserControl的各种属性或行为,那么在UserControl中创建公开属性您需要操作的对象或字段:

 //注意在代码中实例化UserControl时,不会调用UserControl的Load事件! 
public UserControl1()
{
InitializeComponent();
UCToolTip = toolTip1;
UCButton = button1;
}

public ToolTip UC1ToolTip {get;组; }
public Button UC1Button {get;组; }

然后你可以在你的代码中做一些事情,如:

 newUC.UCToolTip.SetToolTip(newUC.UCButton,Papa有一个全新的包。);  


组件依赖于你在每个中看到的特殊私有变量System.ComponentModel Designer.cs文件:private System.ComponentModel.IContainer components = null;当UserControl或Form上放置了Components时,只有那个变量被初始化:this.components = new System.ComponentModel.Container();



Some UserControl中的组件(如Timer)将幸存从一个主机控件迁移到另一个主机控件,没有问题。



但是,ToolTip是一种特殊的组件可能的,< i>延伸< / i>对表单和表单本身的每个控件的能力。 引擎盖下,ToolTip有自己的集合,ComponentCollection,在其Container.Components字段中维护。并且,工具提示在其容器中以特殊方式定位,站点本身是ISite接口的实例。当一个ToolTip在Designer.cs类中初始化时,你会注意到它的构造函数的形式已经完成,它将它的主机Control传递给一个IContainer变量。



当您从某个表单或UserControl的ControlCollection中删除带有工具提示的UserControl时,工具提示站点信息显示为丢失。虽然你可能认为你可以恢复这些信息,但我试图将其作为一个实验:嗯,我所能说的就是我无法通过我尝试过的各种异国情调来实现这一目标。 ToolTip的'Container属性是只读的,但您可以设置'Site属性。


Hi,

I hope somebody can give me a hint why my tooltip shows only when the form is opened for the first time.
The scenario is as follows:
1. run the application
2. check if tooltip is showed, close to form FormWithControl
3. press the button buttonOpen to call formMiddle.ShowConfigUI(), now the tooltip doesn't show any more.

The starting form is Form4, which opens formMiddle, which holds UserControl1 and puts it into FormWithControl. The problem that here occures is taht, that I have one UserControl with a tooltip and the UserControl is moved from one Form into another. Then the tooltip doesn't show any more.

I have folowing things programmed:
1. UserControl - a simple user control with a button and a tooltip set on it
this.toolTip1.SetToolTip(this.button1, "Test button");

2. A container form named "FormWithControl", which displays my user control

public partial class FormWithControl : Form
{
    MiddleClass _formMiddle;
    public FormWithControl(MiddleClass formMiddle)
    {
        InitializeComponent();
        _formMiddle = formMiddle;
    }

    public void InitalizeShow(UserControl1 usctr)
    {
        base.Controls.Add(usctr);
    }

    public void Show(bool flag)
    {
        base.Show();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        base.Close();
    }

    private void FormWithControl_FormClosing(object sender, FormClosingEventArgs e)
    {
        _formMiddle.CloseConfigUI();
    }

    public void RemoveControls()
    {
        base.Controls.RemoveAt(1);
    }
}




3. Control form which can cause to open the form "FormWithControl"

public partial class Form4 : Form
    {
        MiddleClass formMiddle;

        public Form4()
        {
            InitializeComponent();
            formMiddle = new MiddleClass();
            formMiddle.InitConfigUI();
        }

        private void buttonOpen_Click(object sender, EventArgs e)
        {
            formMiddle.ShowConfigUI();
        }
    }



4. A class named MiddleClass with following code

public class MiddleClass
{
    FormWithControl formWithControl;
    UserControl1 userControl1;

    public MiddleClass()
    {
        userControl1 = new UserControl1();
    }

    public void InitConfigUI()
    {
        formWithControl = new FormWithControl(this);
        formWithControl.InitalizeShow(userControl1);
        formWithControl.Show(true);
    }

    public void ShowConfigUI()
    {
        formWithControl = new FormWithControl(this);
        formWithControl.InitalizeShow(userControl1);
        userControl1.Parent = formWithControl;
        formWithControl.Show(true);
        userControl1.Focus();
    }

    public void CloseConfigUI()
    {
        formWithControl.RemoveControls();
        formWithControl.Hide();
    }
}

解决方案

... edit October 20, 2013 ...

Summary:

1. In WinForms, in a UserControl: the ToolTip Component, which is an Extender Provider ... unlike other Components, and Controls ... will not function if you change the Parent of the UserControl to another Form (it will, however, function if you change the Parent of the UserControl to another ContainerControl on the same Form). By "not function," I mean: the ToolTips set at design-time on the UserControl's internal Controls will no longer appear at run-time.

2. The reasons why the ToolTip Component appears to become disabled if its hosting UserControl's Parent is changed to another Form are not clear. Quite possibly, the dependency the ToolTip Component has on its internal pointers to Site and Container are affected.

How to "migrate" a ToolTip in a UserControl if the UserControl's Parent is changed to another Form:

0. for educational purposes:

a. assume we have a WinForm App, with a main Form, 'MainForm, with two Panels on it, 'panel1, 'panel2

b. the App has a UserControl, 'userControl1, which has one Button, and two TextBoxes on it, and has a ToolTip component added to it: button1, textBox1, textBox2, toolTip1.

c. one instance of the UserControl1, 'userControl1, has been drag-dropped into the main Form's 'panel1.

d. the App creates another Form, 'Form1

1. define a public method in the UserControl like this:

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;
    }
}

Since the ToolTips for the Controls in the UserControl are not created at design-time: call the 'ChangeParent method in the UserControl's 'Load EventHandler to initialize them:

private void UserControl1_Load(object sender, EventArgs e)
{
    // assume userControl1's inital Parent is 'panel1
    ChangeParent(Parent);
}

Discussion:

1. since 'ChangeParent is a Public method, it can be called from anywhere that has a reference to an instance of the UserControl 'userControl1. So, if you moved the UserControl to another Form, and wanted to then move it back to its original Parent Form, the second Form would have to have a pointer to the original Form, or the ContainerControl on the original Form where they wished to re-site the UserControl (in this example, that would be 'panel1 in the instance of the MainForm).

2. You can see that what's done here is very much a "hack:" the ToolTips are getting cleared and restored every time the Parent of the UserControl is changed.

Conclusion: Use at your own risk, this kind of hack could well be affected in the future by some change by MS. And, as I stress in the original response to this thread (below), it's my opinion that "migrating" Controls from one ControlContainer, or Form, to another is not good programming practice ... in the long run.

... end edit October 2013 ...

While you have discovered you can remove a Control from a Form, and then add it to the ControlCollection of another Form, make it visible, and use it, there is a structural problem possible with using certain Components when you "migrate" Controls this way, and a ToolTip, even though it doesn't appear in the ToolBox for Visual Studio as a Component, is a Component.

But, before talking about the special nature of a ToolTip, I'd like to say that I think moving Controls from one container, Form, UserControl, to another, or from one TabPage to another TabPage, etc., is a very bad idea, and, inherently, is going to lead to problems later on.

If you want to add a new UserControl to Form3, at run-time, with its ToolTip on a Button, exactly the way you configured the UserControl at design-time: just create a new instance of the UserControl and add it to the Form.

Form3 f3 = new Form3();

UserControl1 newUC1 = new UserControl1();

f3.Controls.Add(newUC1);

// position it, etc.
newUC1.Location = new Point(50,50);

f3.Show();

If you really need to modify, at run-time, various properties or behaviors of the UserControl, then create Public Properties in the UserControl that expose the objects, or fields you need to manipulate:

// 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; }

Then you can do something in your code like:

newUC.UCToolTip.SetToolTip(newUC.UCButton, "Papa's got a brand new bag.");

And now, here's a lot of esoteric detail about Components, and the ToolTip:

Components have a dependency on the special private variable System.ComponentModel you see in every Designer.cs file: private System.ComponentModel.IContainer components = null; When a UserControl, or Form, has Components placed on it, only then is that variable initialized: this.components = new System.ComponentModel.Container();

Some Components in a UserControl, like the Timer, will "survive" migration from one host Control to another with no problem.

But, the ToolTip is a special kind of Component that, potentially, <i>extends</i> capability to every Control on a Form, and the Form, itself. "Under the hood," a ToolTip has its own collection, a ComponentCollection, maintained in its Container.Components field. And, a ToolTip is "sited" in its Container in rather a special way, the "site" itself being an instance of the ISite interface. When a ToolTip is intialized in a Designer.cs Class, you'll note it's done with the form of its constructor that passes its host Control into an IContainer variable.

When you remove a UserControl with a ToolTip from some Form, or UserControl's, ControlCollection, it appears the ToolTip "site" information is "lost." While you might think you could restore that information, and I've tried to do that as an experiment: well, all I can say is that I can't achieve that through a variety of exotic means I've tried. The 'Container property of a ToolTip is read-only, but you can set the 'Site property.


这篇关于当控件移动到另一个窗口时,工具提示不会再出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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