From Dr.WPF 的Tabcontrol的MVVM性能问题

http://groups.google.com/group/wpf-disciples/browse_thread/thread/6f3531a1720252dd?pli=1

 

(moving to public group)


   This topic is on my todo list for my ItemsControl series.  I just  
need to find some blog time.


   I have repeatedly brought this issue up with Microsoft (including  
last week at the summit).  I understand why they chose to implement it  
this way, but its not practical for most TabControl scenarios. I want  
them to add an option to cache the tab items.


   The perf hit is during the building of the tree.  Unfortunately, if  
you're using a typical MVVM approach with a binding on the ItemsSource  
property of the TabControl, the entire tree must be rebuilt each time  
a tab item is selected.  This is usually a very expensive operation.


   To be clear, I don't mind that they unload/reload the items each  
time.  I just don't want the entire tree discarded.  By doing this,  
all state associated with the visuals is lost.  Maintaining that state  
in the VM is usually an unreasonable nightmare.


   The discarding of items is really only a problem when using a  
TabControl in ItemsSource mode.  In Direct mode, the visuals will  
still be unloaded from the tree, but they won't be discarded.  (See  
'C' is for Collection[1] for a description of Direct vs ItemsSource.)


   This means you can solve the problem by creating your own TabItem  
objects and manually adding them to the TabControl's Items  
collection.  Yes, this adds a bunch of overhead to the view (which is  
why I wish Microsoft would solve the problem in the platform), but if  
done right, it still allows an MVVM approach.  You just don't get to  
use an ItemsSource binding on the TabControl. 


   Below is what my view code typically looks like for such an approach:


   private void OnLoaded(object sender, RoutedEventArgs e)
{
    // set initial tabs
    foreach (TabViewModel view in TabsCollection)
    {
        AddTabItem(view);
    }


       // monitor tabs collection for changes so that tabs can be  
updated appropriately
    TabsCollection.CollectionChanged += new  
NotifyCollectionChangedEventHandler(OnViewsCollectionChanged);

 

}


   private void OnViewsCollectionChanged(object sender,  
NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            foreach (TabViewModel view in e.NewItems)
            {
                AddTabItem(view);
            }
            break;

           case NotifyCollectionChangedAction.Remove:
            foreach (TabViewModel view in e.OldItems)
            {
                RemoveTabItem(view);
            }
            break;


           case NotifyCollectionChangedAction.Reset:
            _tabControl.Items.Clear();
            foreach (TabViewModel view in e.NewItems)
            {
                AddTabItem(view);
            }
            break;
    }

 

}


   private void AddTabItem(TabViewModel view)
{
    TabItem item = new TabItem();
    item.DataContext = view;
    item.Content = new ContentControl();
    (item.Content as ContentControl).Focusable = false;
    (item.Content as  
ContentControl).SetBinding(ContentControl.ContentProperty, new  
Binding());
    _tabControl.Items.Add(item);


}


   private void RemoveTabItem(TabViewModel view)
{
    TabItem foundItem = null;
    foreach (TabItem tabItem in _tabControl.Items)
    {
        if (tabItem.DataContext == view)
        {
            foundItem = tabItem;
            break;
        }
    }
    if (foundItem != null)
    {
        _tabControl.Items.Remove(foundItem);
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值