C#:ToolStripDropDown不处理/销毁句柄 [英] C#: ToolStripDropDown doesn't Dispose/DestroyHandle

查看:317
本文介绍了C#:ToolStripDropDown不处理/销毁句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ToolStripDropDown来显示一个选择弹出窗口.

I'm using the ToolStripDropDown to show up an selectionpopup.

ToolStripDropDown包含一些带有正在运行的线程的自定义控件. 线程以OnHandleDestroyed事件结束,但是由于某些原因,ToolStripDropDown在关闭后没有处置/销毁它的句柄.

The ToolStripDropDown contains a few custom controls with running Threads. The Threads ends with the OnHandleDestroyed event, but for some reason the ToolStripDropDown doesn't dispose/destroy it's handle after closing.

在封闭事件上放置ToolStripDropDown给我一个例外,因为仍然有任何东西可以访问ToolStripDropDown.

Disposing the ToolStripDropDown on the closed-event gives me an exception because anything still accesses the ToolStripDropDown.

我怎么知道自定义控件是否仍在使用或不结束线程?

How do I know if the custom Control is still in use or not to end the thread?

自定义控件:

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:

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

在进行了同样的测试之后,我无法处理toolstripdropdown. 作为一种解决方法,我只是在toolstripdropdown关闭时销毁了手柄.

After same more testing i wasn't able to dispose the toolstripdropdown. As a workaround i'm just destroying the handle on close of the toolstripdropdown.

        protected override void OnClosed(ToolStripDropDownClosedEventArgs e)
        {
            base.OnClosed(e);
            this.DestroyHandle();
        }

推荐答案

ToolStrips存在一个非常持久的错误(声称已修复,但我仍然有问题),在该错误中,他们向SystemEvents.UserPreferenceChanged注册了一个事件处理程序,以便能够重新绘制如果用户在OS中更改全局样式设置.

ToolStrips have a very persistent bug (claimed to be fixed, but I still have problems) where they register an event handler to SystemEvents.UserPreferenceChanged to be able to repaint if the user changes global style settings in the OS.

我发现的唯一解决方法是,通过枚举SystemEvents.UserPreferenceChanged中的处理程序来删除附加的工具条,并在处置控件后将其删除.

The only workaround I have found is to remove the attached toolstrips by enumerating the handlers in the SystemEvents.UserPreferenceChanged and removing them upon disposal of the control.

ToolStrip内存泄漏

http://connect. microsoft.com/VisualStudio/feedback/details/115600/toolstrip-leaks-after-calling-dispose#

这篇关于C#:ToolStripDropDown不处理/销毁句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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