WPF控制破坏 [英] WPF controls destroyement

查看:111
本文介绍了WPF控制破坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,
我是wpf的新手.

->在Windows窗体中,添加到窗体中的任何控件或UserControl
可以从调用.Dispose();的Form中移除并销毁.

->问题是如何在Wpf控件上执行类似的操作,甚至
在我自己的UserControls上?

Hello,
I''m new to wpf..

-> In Windows Forms any Control or UserControl added to the Form
can be removed and destroyed from the Form calling .Dispose();

-> The question is how to do similar operation on Wpf Controls, even
on my own UserControls ?

Thank''s!

推荐答案

不正确:此Dispose与从表单中删除任何内容无关.

以及您如何处理Dispose(/* without paramters */) ystem.IDisposable.Dispose.请阅读有关此界面的信息:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx [^ ].

您只需要配置一些实现此接口的东西即可.如果未实现此接口(不在基本类型列表中),则没有任何可处置"的. (好吧,有一些名为Dispose的方法与此接口无关.我不是在谈论它们; WPF UI元素都没有.)

背景:

在.NET中,最终使用垃圾收集器(GC)回收变为无法访问的对象的托管内存.通常,用户对销毁和回收内存没有任何控制权.但是需要显式回收非托管内存. System.IDisposable.Dispose通常用于此目的,但这不是此接口和此方法的唯一用法-它可以是任何东西,无论您实现什么.您可以通过自己的任何类或结构来实现此接口.库System.Windows.Forms使用此机制,因为它基于旧版Windows API,因此会占用大量内存.

相反,WPF不需要使用这种过时的API.实际上,它与Windows API无关,因为大多数WPF都直接使用DirectX. DirectX是一种硬件/固件(不仅是操作系统)支持的多平台技术.因此,库代码无需处理(但是我不确定它是否100%免费;我从来没有搜索过,这很容易;无论如何,我原则上只是在解释为什么UI元素不是一次性的:不需要).

—SA
Not true: this Dispose have nothing to do with removing anything from a form or anything like this.

And what do you thing Dispose(/* without paramters */)ystem.IDisposable.Dispose. Please read about this interface:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx[^].

You only need to disposing something which implements this interface. If this interface is not implemented (not in the base types list), there is nothing to "dispose". (Well, there are methods called Dispose not related to this interface. I''m not talking about them; and WPF UI elements have none of them.)

Background:

In .NET, the managed memory is reclaimed using the Garbage Collector (GC) eventually, for the objects that becomes unreachable. Normally, the users do not have any control on the destruction and reclaiming memory. But unmanaged memory needs to be reclaimed explicitly. The System.IDisposable.Dispose is usually used for this, but this is not the only use of this interface and this method — it can be anything, whatever you implement. You can implement this interface by any of your own classes or structures. The library System.Windows.Forms uses this mechanism, because it is based on legacy Windows API, thus using umnamaged memory.

In contrast, WPF does not need to use such outdated API. In fact, it have very little to do with Windows API, as most of WPF uses DirectX, well— directly; and DirectX is a multi-platform technology supported by hardware/firmware, not just by OS. So, the library code is free from disposing (but I''m not sure if it is 100% free; I never searched for that, which would be easy; anyway, I just explain in principle, why UI elements are not disposable: no need).

—SA


在删除控件之前,可以使用 WeakEventManager + IWeakEventListener 删除控件的EventHandler.否则会泄漏内存
最后调用GC.

注意:示例仅供参考,当使用 WeakListternImp 中的事件"click"时,它必须是Action或委托
此处的示例:您可以参考:
WeakEvent任何事件

file:MainWindow.cs
You can use WeakEventManager + IWeakEventListener to Remove EventHandler of Control before Remove Control. Else can Leak Memory
Finally call GC.

Note: Sample only to reference, when use Event ''click'' in WeakListternImp, it must a Action or delegate
Sample here: You can reference:
WeakEvent Any Event

file:MainWindow.cs
// Author: Ledangkhoa
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;

namespace WpfApplication9
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var lis = new WeakListternImp{Name = "Click"};
            WeakImp.AddHandle(button1, lis);

            var lisc = new WeakListternImp { Name = "Checked" };
            WeakImp.AddHandle(checkBox1, lisc);
            var lis2 = new WeakListternImp { Name = "PreviewMouseDoubleClick" };
            WeakImp.AddHandle(button2, lis2);
        }
    }

    class WeakImp : WeakEventManager
    {
       static Dictionary<object,WeakListternImp> hold = null;
       static Dictionary<object, Delegate> dele = null;
        
        internal static void AddHandle(object source, IWeakEventListener handler)
        {
            if (hold == null)
            {
                hold = new Dictionary<object,WeakListternImp>();
                
            }
            hold.Add(source, handler as WeakListternImp);
            Current.ProtectedAddListener(source, handler);

        }
        internal static void RemoveHandle(object source, IWeakEventListener handler)
        {
            Current.ProtectedRemoveListener(source, handler);
        }

        public static WeakImp Current
        {
            get
            {
                WeakImp man = GetCurrentManager(typeof(WeakImp)) as WeakImp;
                if (man == null)
                {
                    man = new WeakImp();
                    SetCurrentManager(typeof(WeakImp), man);
                }
                return man;
            }
        }

        protected override void StartListening(object source)
        {
            Type ty = source.GetType();
            var t = from x in source.GetType().GetEvents();
                    where x.Name == hold[source].Name
                    select x;

            MethodInfo meinf = this.GetType().GetMethod("Active",BindingFlags.Instance| BindingFlags.NonPublic);

            Type typehandler = t.First().EventHandlerType;

            EventInfo eventinfo = t.First();
            if (dele==null)
            {
                dele = new Dictionary<object, Delegate>();
            }
            dele.Add(source,Delegate.CreateDelegate(typehandler,this,meinf));
            eventinfo.AddEventHandler(source, dele[source]);
        }

        void Active(object s, System.EventArgs e)
        {
            DeliverEvent(s, e);
        }


        protected override void StopListening(object source)
        {
            Type ty = source.GetType();
            var t = from x in source.GetType().GetEvents();
                    where x.Name == hold[source].Name
                    select x;

            MethodInfo meinf = this.GetType().GetMethod("Active", BindingFlags.Instance | BindingFlags.NonPublic);

            Type typehandler = t.First().EventHandlerType;

            EventInfo eventinfo = t.First();
            eventinfo.RemoveEventHandler(source, dele[source]);
            hold.Remove(source);
            dele.Remove(source);
            if (hold.Count == 0)
            {
                hold = null;
            }
            if (dele.Count == 0)
            {
                dele = null;
            }
            GC.Collect();
        }
    }
    class WeakListternImp : IWeakEventListener
    {
        public string Name { get; set; }
        public void click(object o, EventArgs e)
        {
            MessageBox.Show(o.ToString()+Name);
            If(Name == "Click")
                WeakImp.RemoveHandle(o, this);

        }
        public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
        {
            click(sender, e);
            
            return true;
        }
    }
}



file:MainWindow.xaml
<窗口x:class ="WpfApplication9.MainWindow" xmlns:x =#unknown">
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Title ="MainWindow" Height ="350" Width ="525">
< grid>
< button content =点击" height ="23" horizo​​ntalalignment ="Left" margin ="112,41,0,0" name ="button1" verticalalignment ="Top" width ="75"/>
< checkbox content =检查" height ="16" horizo​​ntalalignment ="Left" margin ="116,115,0,0" name ="checkBox1" verticalalignment ="Top">
< button content =双击" height ="23" horizo​​ntalalignment ="Left" margin ="328,70,0,0" name ="button2" verticalalignment ="Top" width ="120"/>


希望对您有用!



file:MainWindow.xaml
<window x:class="WpfApplication9.MainWindow" xmlns:x="#unknown">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<grid>
<button content="click on" height="23" horizontalalignment="Left" margin="112,41,0,0" name="button1" verticalalignment="Top" width="75" />
<checkbox content="check on" height="16" horizontalalignment="Left" margin="116,115,0,0" name="checkBox1" verticalalignment="Top">
<button content="double click on" height="23" horizontalalignment="Left" margin="328,70,0,0" name="button2" verticalalignment="Top" width="120" />


Hope useful with you!


您需要从父级中删除,但也要知道父级是什么.

例如

You need to remove from the parent but also know what the parent is.

For example

((Grid)customControl.Parent).Children.Remove(customControl);



如果您不知道父类型,则可以进行一些可视化爬树.但是,那要复杂得多.



If you do not know the parent type you can do some visual tree climbing. That is more complicated though.


这篇关于WPF控制破坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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