Windows Develop Bookmark and Share   
 index > Windows Forms General > References to Controls being held by HelpProvider
 

References to Controls being held by HelpProvider

Is there a way to get a HelpProvider to release a reference to a Control it has been passed in a call to SetShowHelp or SetHelpKeyword? ResetShowHelp and SetShowHelp(Control, false) do not do the trick.

Our application has a singleton HelpProvider. Forms access this singleton in their Form_Load, but this appears to cause an unavoidable object leak (our application creates and destroys forms over and over).
omgtifbs  Tuesday, August 07, 2007 12:26 AM
Hmm, "unsupported use of a component" jumps to mind.
nobugz  Tuesday, August 07, 2007 5:42 AM
Using a singleton HelpProvider is not a good idea, make it a component of the form so it gets disposed together with the form. Nevertheless, ResetShowHelp() removes the control from the internal Hashtable it keeps. With a singleton, you'd have to iterate the Controls collection of the form and any container controls in the FormClosing event:

private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
releaseHelp(this.Controls);
}
private void releaseHelp(Control.ControlCollection ctls) {
foreach (Control ctl in ctls) {
helpProvider1.ResetShowHelp(ctl);
releaseHelp(ctl.Controls);
}
}

Where helpProvider1 would be your HelpProvider instance.
nobugz  Tuesday, August 07, 2007 12:51 AM
Thanks again, Hans. I think we'll have to go with making the HelpProvider a component of the form.

However, if ResetShowHelp() is supposed to release the reference, then there appears to be a bug in it. I can't find any way to get a HelpProvider to release a reference to a Form.

On my system, in this application it takes about 3 or 4 iterations of creating and closing Form2 before I get an out of memory error. Can anybody rewrite Form1.form2_FormClosed() such that the reference is released?

public partial class Form1 : Form
{
private HelpProvider m_HelpProvider = new HelpProvider();
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();

Form2 form2 = new Form2();
m_HelpProvider.SetHelpNavigator(form2, HelpNavigator.Index);
form2.FormClosed += new FormClosedEventHandler(form2_FormClosed);
form2.Show();
}

void form2_FormClosed(object sender, FormClosedEventArgs e)
{
m_HelpProvider.ResetShowHelp((Control)sender);
// this doesn't work either:
// m_HelpProvider.SetShowHelp((Control)sender, false);
}
}

public partial class Form2 : Form
{
private int[] x = new int[59999999];
public Form2()
{
InitializeComponent();
}
}






omgtifbs  Tuesday, August 07, 2007 3:44 AM
The SetHelpNavigator() method call is the killer. That adds a reference to the form to another hash table that can't be cleared.
nobugz  Tuesday, August 07, 2007 4:33 AM
The same goes for all the Set methods on HelpProvider. The object is impossible to use in such a way that it doesn't permanently grab references. This seems like a bug.
omgtifbs  Tuesday, August 07, 2007 4:46 AM
Hmm, "unsupported use of a component" jumps to mind.
nobugz  Tuesday, August 07, 2007 5:42 AM

You can use google to search for other answers

Custom Search

More Threads

• Radiobutton Focus Problem
• How to activate the form and its control without first calling show() and make it on screen?
• Problem with Custom property descriptor
• C# DataGridView
• Need help with textbox
• Getting Extended System Colours
• Need advice on what to use here...
• How can I disable a listBox item?
• Combobox keypress Problem
• Allignment of windows forms