代码改变世界

修复TabControl在Binding情况下Canvas被复用的问题

2010-05-03 10:16  Franz  阅读(475)  评论(0编辑  收藏  举报

N些时间以前我发表过一片日志“DataBinding没有想象的那么智能”,里面演示了当TabControl在Binding的状态下内容为Canvas对象时会出问题,TabControl的内容对象在视觉树上不会被替换掉,而是根据Binding把相应的部分内容替换了。导致的问题是Canvas上绘制的任何图形都被共用了。切换标签是没有任何改变的迹象的。

 

怎么说呢,TabControl这么做不能说是他的Bug,我认为更应该是wpf的一个特性而已,就是WPF不会在每次更新TabControl时(即切换标签时)创建新的视觉树对象,提高了对象的复用度。这个好处也是导致我们的Canvse被共用的根本原因。如果不使用Binding根本就不会有这样的问题,因为每一个TabItem都用自己的一个Content值,TabControl会加载TabItem的Content内容来显示的,不会从模板缓存中取视觉对象的。

 

知道以上问题那解决这个问题自然也就不怎么困难了。

查看TabControl的方法找到,“TabControl.GetContainerForItemOverride 方法” MSDN上解释如下

创建或标识用于显示指定项的元素。

我们来重载此方法即可。

protected override DependencyObject GetContainerForItemOverride()
{
     
return new TabItem{Content = new Canvas()}; 
}

现在我们在Binding的时候手动的创建了Canvas对象,这样就不会在从缓存中取了。

当然这个可以做的更智能一点,不方Canvas,而是从一个DP上去取就灵活多了。这是后话了。现在我只是想展示一下当前的解决办法而已!