是否应将Silverlight控件重新加载到页面上? [英] Should Silverlight Controls be re-loaded onto pages?

查看:65
本文介绍了是否应将Silverlight控件重新加载到页面上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个月前,我开始自行开发Silverlight应用程序.我很快发现我无法获得大多数控件的预期垃圾回收.我在WinDBG和ANTS内存分析器上苦苦挣扎了大约一周,然后在Silverlight论坛(http://forums.silverlight.net/forums/t/171739.aspx)上找到了"DataTemplate内存泄漏"链.

Some months ago I started developing a Silverlight application on my own. I quickly discovered that I was unable to get expected garbage collection for most of my controls. I struggled for about a week with WinDBG and ANTS memory profiler and then found the "DataTemplate memory leak" strand on the Silverlight forum (http://forums.silverlight.net/forums/t/171739.aspx).

鉴于很多人似乎对各种内存问题感到沮丧,所以我决定推迟对内存状况的进一步调查,直到解决最明显的问题为止.

Given that so many people seemed to be frustrated with various memory issues I decided to delay further investigation into the memory situation until the most obvious issue was resolved.

无论如何,现在我又在调查这个问题,我意识到我遇到的问题比我最初想的要根本得多.在以下情况下,我只是没有编写垃圾可收集Silverlight控件的范例:a)控件具有可以绑定的依赖项属性,并且b)可以从一个控件中卸载该控件,然后再将其再次加载.

Anyway, now I'm looking into the issue again and I realise that the problem I'm having is much more fundamental than I had first thought. I simply don't have a paradigm for writing garbage collectable Silverlight controls when: a) the control has dependency properties that can be bound to, and b) the control can be unloaded from one control and then subsequently loaded again.

我开始认为这些要求中的第二个要求太高了.有人可以确认吗?

I'm starting to think that the second of these demands is too great. Can anyone confirm this?

为了提供更多细节,我可以为编写良好的,可垃圾回收的Silverlight控件而想到的最可靠的模式如下:

To give a tiny bit more detail, the most robust pattern I can come up with for writing good, garbage collectable Silverlight controls is as follows:

1)当应用控件的模板时(在OnApplyTemplate替代中),我在本地属性和TemplateParts之间设置了任何内部绑定.例如,我可能会在名为CanSearch的本地属性和按钮之间设置绑定.

1) When a Control's Template is applied (in the OnApplyTemplate override) I setup any internal bindings between local properties and TemplateParts. For example, I might setup a Binding between a local property called CanSearch and a button.

if (x_Button_Search != null)
            {
                Binding b = new Binding("CanSearch");
                b.Source = this;
                this.x_Button_Search.SetBinding(Button.IsEnabledProperty, b);
            }

2)当控件引发Unloaded事件时,我清除了内部绑定并取消了所有事件处理程序的连接.

2) When the Control raises the Unloaded event, I clear the internal bindings and un-wire any eventhandlers.

if (x_Button_Search != null)
            {
                this.x_Button_Search.ClearValue(Button.IsEnabledProperty);
            }

这似乎是确保x_Button_Search元素与Control之间不存在任何尾随引用的最干净的方法.我不知道这是否绝对必要.

This seems to be the cleanest way of ensuring that no trailing references exist between the x_Button_Search element and the Control. I don't know if this is strictly necessary.

3)同样,当控件引发Unloaded事件时,我清除了对现有依赖项属性的绑定.

3) Again, when the Control raises the Unloaded event, I clear bindings to existing dependency properties.

 this.ClearValue(SearchParametersProperty);

如果我不这样做,可能会导致泄漏.例如,如果SearchParameters属性绑定到某些INotifyPropertyChanged对象,则对控件的引用仍保留在绑定了INotifyPropertyChanged对象的PropertyChanged事件中,即使该控件已卸载,即,只要型号,这可能是不希望的.

If I fail to do this I can cause leaks. For example, if the SearchParameters property was bound to some INotifyPropertyChanged object then a reference to the Control remains in the PropertyChanged event on the INotifyPropertyChanged object to which I am bound even after the control has been unloaded i.e. the View will stay around as long as the Model and that may not be desired.

4)我闪烁" Template值,以便下次加载控件时,重新应用模板,并再次触发OnApplyTemplate方法.

4) I 'flicker' the Template value so that next time the control is loaded, the template is reapplied and the OnApplyTemplate method is fired again.

var oldTemplate = this.Template;
            this.Template = null;
            this.Template = oldTemplate;

执行4的原因是,当控件重新加载到页面上时,我需要恢复绑定.在Silverlight中,可以通过两个入口点执行此操作:在OnApplyTemplate重写中或在控件触发Loaded事件之后.由于我想在控件加载之前强制执行绑定值(以避免闪烁),因此只有一个可用的入口点OnApplyTemplate.我必须使模板闪烁,以便在重新加载控件时强制重新应用模板.

The reason to do 4 is that I need to reinstate bindings when the Control is reloaded onto a page. In Silverlight, there are two points of entry through which to do this: in the OnApplyTemplate override or after the control fires the Loaded event. As I want to enforce binding values before the control has been loaded (to avoid flickering), there is only one available entry point available, OnApplyTemplate. I have to flicker the template in order to force the template to reapply when the control is reloaded.

看来,直到第3点的模式都是提供垃圾收集控件的最低要求.

It appears this pattern up to point 3 is the bare minimum for providing garbage collected controls.

当您要卸载控件(例如,从面板中删除它)并随后重新加载它时,我的问题就来了.在第3点中,控件上的所有依赖项属性均已设置为null.例如,假设控件的声明中存在绑定,例如.据我所知,一旦SearchParameters的值设置为null,就无法恢复此Binding,毕竟它不是Template的一部分.结果是,当重新加载控件时,就好像SearchParameters的值为null.因此,我跳过了模式中的第3步,得到了一个没有垃圾回收的可重载控件,或者我保留了3并得到了一个不可重载的控件.

My problem comes when you want to unload your control (remove it from a Panel for example) and subsequently reload it. Any dependency properties on the control have been set to null in point 3. For example, imagine there is a binding on the declaration of the control e.g. . As far as I can tell, there is no way of reinstating this Binding once the value of SearchParameters has been set to null, it's not part of a Template after all. The result is that when the control is re-loaded it's as if the value of SearchParameters was null. So I either skip out step 3 in the pattern and get a reloadable control that is not garbage collected, or I keep 3 and get an unreloadable control.

推荐答案

您在1)中所做的事情似乎真的很奇怪.为什么要在代码中而不是在xaml中启动对模板的绑定? 使用此软件,我们已经在Silverlight中解决了很多内存泄漏问题

What you do in 1) seems really strange. Why initiating a binding to the template in code and not in xaml? We have solved lots of memory leak issues in silverlight using this software

http://memprofiler.com/

编辑

要对绑定进行更多控制,可以使用

For more control over the binding, you can use

{Binding Property, RelativeSource={RelativeSource TemplatedParent}}

这样,隐式转换器将按预期使用,您也可以指定自己的转换器.而且我相信BindingMode TwoWay也可以正常工作. 祝你好运!

That way the implicit converters are used as expected and you can also specify your own. And I believe that BindingMode TwoWay works as well. Good luck!

这篇关于是否应将Silverlight控件重新加载到页面上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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