WPFPreservesTabControlState我已经阅读了帖子@HowtoStopWpfTabcontrolfromUnloadingVisualTreeonTabChange,但我无法让它工作,我必须缺少一些东西。请帮忙。谢谢,我正在使用示例项目中的类TabControlEx@http://www.pluralsight-training.net/community/blogs/eburke/archive/2009/04/30/keeping-the-wpf-tab-control-from-destroying-its-children.aspxmaintab的数据源是Tabs.TabItemspublicObservableCollectionTabItems{get{return_items;每个TabItem都使用我一直在使用的那个链接中的代码,没有任何问题,尽管我注意到自从我第一次获得代码以来网站已经发生了变化。您可能想检查我所拥有的和网站所做的之间是否存在任何代码差异。这是我们在更改网站之前获得的代码://扩展的TabControl保存显示的项目,这样你就不会受到//在切换选项卡时卸载和重新加载VisualTree的性能影响//从http://www.pluralsight-training.net/community/blogs/eburke/archive/2009/04/30/keeping-the-wpf-tab-control-from-destroying-its-children.aspx//并进行了一些修改,因此它重用了进行拖放操作时TabItem的ContentPresenter[TemplatePart(Name="PART_ItemsHolder",Type=typeof(Panel))]publicclassTabControlEx:System.Windows.Controls.TabControl{//持有所有项目,但只标记当前选项卡的项目作为可见的私有面板_itemsHolder=null;//临时保留已删除的项目,以防这是拖放操作privateobject_deletedObject=null;publicTabControlEx():base(){//这是必要的,以便我们获得初始数据绑定选定项this.ItemContainerGenerator.StatusChanged+=ItemContainerGenerator_Sta改变了;}//////如果容器完成,生成选定的项目/////////voidItemContainerGenerator_StatusChanged(objectsender,EventArgse){if(this.ItemContainerGenerator.Status==GeneratorStatus.ContainersGenerated){this.ItemContainerGenerator.StatusChanged-=ItemContainerGenerator_StatusChanged;更新选定项();}}//////获取ItemsHolder并生成任何子项///publicoverridevoidOnApplyTemplate(){base.OnApplyTemplate();_itemsHolder=GetTemplateChild("PART_ItemsHolder")作为面板;更新选定项();}//////当项目改变时,我们删除所有生成的面板子项并根据需要添加任何新的//////protectedoverridevoidOnItemsChanged(NotifyCollectionChangedEventArgse){base.OnItemsChanged(e);如果(_itemsHolder==null){返回;}switch(e.Action){caseNotifyCollectionChangedAction.Reset:_itemsHolder.Children.Clear();如果(base.Items.Count>0){base.SelectedItem=base.项目[0];更新选定项();}休息;caseNotifyCollectionChangedAction.Add:caseNotifyCollectionChangedAction.Remove://搜索由拖放操作引起的最近删除的项目if(e.NewItems!=null&&_deletedObject!=null){foreach(varitemine.NewItems){if(_deletedObject==item){//如果新项目与最近删除的项目相同(即拖放事件)//则取消删除并重新使用ContentPresenter,因此它不必//重绘.我们确实需要将演示者链接到新项目(使用标签)ContentPresentercp=FindChildContentPresenter(_deletedObject);如果(cp!=null){intindex=_itemsHolder.Children.IndexOf(cp);(_itemsHolder.Children[index]asContentPresenter).Tag=(itemisTabItem)?项目:(this.ItemContainerGenerator.ContainerFromItem(item));}_deletedObject=null;}}}if(e.OldItems!=null){foreach(varitemine.OldItems){_deletedObject=item;//我们想要以稍微晚一点的优先级运行它,以防这是一个拖放操作,这样我们就可以重用模板this.Dispatcher.BeginInvoke(DispatcherPriority.DataBind,newAction(delegate(){if(_deletedObject!=null){ContentPresentercp=FindChildContentPresenter(_deletedObject);if(cp!=null){this._itemsHolder.Children.Remove(cp);}}}));}}UpdateSelectedItem();休息;caseNotifyCollectionChangedAction.Replace:thrownewNotImplementedException("Replacenotimplementedyet");}}//////更新ItemsHolder中的可见子对象//////protectedoverridevoidOnSelectionChanged(SelectionChangedEventArgse){base.OnSelectionChanged(e);更新选定项();}//////为所选项目生成一个ContentPresenter///voidUpdateSelectedItem(){if(_itemsHolder==null){return;}//如有必要,生成一个ContentPresenterTabItemitem=GetSelectedTabItem();如果(项目!=null){CreateChildContentPresenter(项目);}//显示正确的孩子Visibility.Visible:Visibility.Collapsed;}}//////为给定项目(可以是数据或TabItem)创建子ContentPresenter/////////ContentPresenterCreateChildContentPresenter(objectitem){if(item==null){returnnull;}ContentPresentercp=FindChildContentPresenter(item);如果(cp!=null){返回cp;}//要添加的实际孩子。cp.Tag是对TabItem的引用cp=newContentPresenter();cp.Content=(项目是TabItem)?(项目作为TabItem)。内容:项目;cp.ContentTemplate=this.SelectedContentTemplate;cp.ContentTemplateSelector=this.SelectedContentTemplateSelector;cp.ContentStringFormat=this.SelectedContentStringFormat;cp.Visibility=Visibility.Collapsed;cp.Tag=(项目是TabItem)?项目:(this.ItemContainerGenerator.ContainerFromItem(item));_itemsHolder.Children.Add(cp);返回cp;}//////找到给定对象的CP。数据可以是TabItem或一段数据/////////ContentPresenterFindChildContentPresenter(objectdata){if(dataisTabItem){data=(dataasTabItem).Content;}如果(数据==null){返回null;}如果(_itemsHolder==null){返回null;}foreach(ContentPresentercpin_itemsHolder.Children){if(cp.Content==data){returncp;}}返回空值;}//////从TabControl复制;希望它在那个类中受到保护而不是私有的//////protectedTabItemGetSelectedTabItem(){objectselectedItem=base.SelectedItem;如果(selectedItem==null){返回null;}if(_deletedObject==selectedItem){}TabItemitem=selectedItemasTabItem;if(itemitem==null){=base.ItemContainerGenerator.ContainerFromIndex(base.SelectedIndex)asTabItem;}归还物品;我确实对原始代码进行了一些更改,因为我拖放了选项卡并且不想在删除项目并重新添加选项卡时重新创建选项卡,但老实说,我已经忘记了这么久我忘记了我不是什么我做了一个快速测试来仔细检查,是的,它确实保留了您的非约束值,例如选定值或扩展值。编辑为了回应您的评论,将DataTemplates放入您的资源中,定义每个选项卡使用哪个UserControl。当TabControl尝试绘制每个选项卡的内容时,它将使用您为该数据类型定义的任何DataTemplate视图模型...publicMyViewModelConstructor(){TabItems.Add(NewTabAViewModel{Header="TabA"});TabItems.Add(NewTabBViewModel{Header="TabB"});}EDIT#2TextXAMLbasedonyourrequest我放弃了解决方法,它只是在我的情况下不起作用。我购买了第3方WPF库(DevExpressWPF)来解决这个问题。谢谢。以上就是C#学习教程:WPF保留Tab控件状态共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:
