C #: ToolStripDropDown ne doit pas être éliminé / DestroyHandle
-
26-10-2019 - |
Question
J'utilise le ToolStripDropDown
pour mettre en avant un selectionpopup.
Le ToolStripDropDown
contient quelques contrôles personnalisés avec des fils en cours d'exécution.
Les fils se termine par l'événement OnHandleDestroyed, mais pour une raison quelconque le ToolStripDropDown
ne doit pas être éliminé / détruire de poignée après la fermeture.
Mise au rebut du ToolStripDropDown
sur la fermeture événement me donne une exception parce que tout accès reste le ToolStripDropDown.
Comment puis-je savoir si la mesure de contrôle est toujours en cours d'utilisation ou non de mettre fin le fil?
Custom-Control:
public class CControl : Control
{
Thread StyleThread;
Object lockOBJ = new Object();
bool abortthread = false;
public CControl()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.Selectable, false);
StyleThread = new Thread(new ThreadStart(this.StyleDelegate));
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if(!StyleThread.IsAlive)
StyleThread.Start();
}
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
lock (lockOBJ)
{
abortthread = true;
}
if (StyleThread.IsAlive)
{
StyleThread.Join(100);
}
}
...
}
ToolStripDropDown-Control:
public class AddPopUp : UserControl
{
/*
------------------------------------
This Control contains some CControls
------------------------------------
*/
public void Show(Control control)
{
TSDD tsdd = new TSDD(this);
Point screenpoint = control.PointToScreen(new Point(0, 0));
tsdd.Show(control,new Point(0, -tsdd.Height ));
}
class TSDD : ToolStripDropDown
{
private Control Control { get; set; }
public TSDD(Control control)
{
this.Control = control;
this.DropShadowEnabled = false;
ToolStripControlHost ch = new ToolStripControlHost(control);
this.Items.Add(ch);
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, Control.Size.Width + 16, Control.Size.Height + 18, specified);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
unchecked
{
cp.Style |= (int)0x80000000;
cp.Style |= 0x40000;
}
return cp;
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x84)
{
m.Result = (IntPtr)1;
return;
}
base.WndProc(ref m);
}
}
}
EDIT:
Après même plus de tests je n'ai pas pu disposer le ToolStripDropDown. Pour contourner ce problème, je suis juste détruire la poignée près du ToolStripDropDown.
protected override void OnClosed(ToolStripDropDownClosedEventArgs e)
{
base.OnClosed(e);
this.DestroyHandle();
}
La solution
toolstrips un bug très persistant (prétendu être fixé, mais j'ai encore des problèmes) où ils enregistrent un gestionnaire d'événements à SystemEvents.UserPreferenceChanged pour pouvoir repeindre si l'utilisateur change les paramètres de style global dans le système d'exploitation.
La seule solution que j'ai trouvé est d'enlever les toolstrips attachés en énumérant les gestionnaires dans le SystemEvents.UserPreferenceChanged et les retirer lors de la cession du contrôle.