WPF TabControl - 防止选项卡更改时卸载?
当 WPF 选项卡控件中的选项卡发生更改时,是否有办法防止选项卡卸载/重新加载?或者,如果这是不可能的,是否有推荐的方法来缓存选项卡内容,以便不必在每次选项卡更改时重新生成它们?
例如,一个选项卡的 UI 是完全可定制的并存储在数据库中。当用户选择要处理的对象时,自定义布局中的项目将填充该对象的数据。用户期望初始加载或检索数据时出现轻微延迟,但在选项卡之间来回更改时不会出现延迟,并且更改选项卡时的延迟非常明显。
Is there a way to prevent the Tab Unload/Reload when a tab changes in a WPF tab control? Or if that is not possible, is there a recommended method for caching the tabs contents so they don't have to be regenerated with each tab change?
For example, one tab's UI is completely customizable and stored in the database. When the user selects an object to work on, the items in the customized layout get populated with that object's data. Users expect a minor delay on initial load or when retrieving data, but not when changing back and forth between tabs, and the delay when changing tabs is very noticeable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在这里找到了一个解决方法(web-archive-link,因为网站已关闭): https://web.archive.org/web/20120429044747/http://eric.burke.name/dotnetmania/2009/04/26/22.09。 28
它基本上存储选项卡的 ContentPresenter 并在切换选项卡时加载它而不是重绘它。拖/放选项卡时它仍然会导致延迟,因为这是一个删除/添加操作,但是经过一些修改,我也让它消失了(以较低的调度程序优先级运行删除代码,然后添加代码,所以添加操作有机会取消删除操作并使用旧的 ContentPresenter 而不是绘制新的)
编辑:上面的链接似乎不再起作用,所以我将在此处粘贴代码的副本。它已进行了一些修改以允许拖放,但它仍然应该以相同的方式工作。
I found a workaround here (web-archive-link, since site is down): https://web.archive.org/web/20120429044747/http://eric.burke.name/dotnetmania/2009/04/26/22.09.28
It basically stores the ContentPresenter of the tab and loads that up when switching tabs instead of redrawing it. It was still causing the delay when dragging/dropping tabs since that was an remove/add operation, however with some modifications I got that to go away as well (ran the Remove code at a lower dispatcher priority then the Add code, so the add operation had a chance to cancel the Remove operation and use the old ContentPresenter instead of drawing a new one)
Edit: The link above appears to no longer work, so I'll paste a copy of the code here. It's been modified a bit to allow dragging/dropping, but it should still work the same way.
除此之外,我遇到了类似的问题,并设法通过缓存表示后面代码中选项卡项内容的用户控件来解决它。
在我的项目中,我有一个绑定到集合(MVVM)的选项卡控件。但是,第一个选项卡是概述,显示列表视图中所有其他选项卡的摘要。我遇到的问题是,每当用户将其选择从项目选项卡移至概述选项卡时,概述就会使用所有摘要数据重新绘制,这可能需要 10-15 秒,具体取决于集合中的项目数量。 (请注意,它们没有从数据库或其他任何东西重新加载实际数据,这纯粹是花费时间绘制摘要视图)。
我想要的是,摘要视图的加载仅在首次加载数据上下文时发生一次,并且选项卡之间的任何后续切换都是即时的。
解决方案:
涉及的类:
MainWindow.xaml - 包含选项卡控件的主页。
MainWindow.xaml.cs - 上面的代码隐藏。
MainWindowViewModel.cs - 上述视图的视图模型,包含集合。
Overview.xaml - 绘制概述选项卡项内容的用户控件。
OverviewViewModel.cs - 上述视图的视图模型。
步骤:
用名为“OverviewPlaceholder”的空白用户控件替换“MainWindow.xaml”中用于绘制概述选项卡项的数据模板
在“MainWindowViewModel.cs”中公开对“OverviewViewModel”的引用
添加静态引用“MainWindow.xaml.cs”中的“Overview”
将事件处理程序添加到用户控件“OverviewPlaceholder”的加载事件中,仅当该方法为 null 时,才会实例化对“Overview”的静态引用,将此引用的数据上下文设置为当前数据上下文中的“OverviewViewModel”引用(即“MainWindowViewModel”),并将占位符的内容设置为静态引用向“Overview”
现在,概述页面仅绘制一次,因为每次加载它(即用户单击概述选项卡)时,都会将已呈现的静态用户控件放回到页面上。
Just to add to this, I had a similar problem and managed to solve it by caching a user control that represented the contents of a tab item in the code behind.
In my project I have a tab control that is bound to a collection (MVVM). However the first tab is an overview that shows a summary of all of the other tabs in a list view. The problem I was having was that whenever a user moves their selection from an item tab to the overview tab, the overview is redrawn with all of the summary data, which can take 10-15 seconds depending on the number of items in the collection. (note their is no reloading of actual data from a db or anything, it is purely the drawing of the summary view that was taking the time).
What I wanted was for this loading of the summary view to only occur once when the data context is first loaded and any subsequent switching between tabs to be instantaneous.
Solution:
Classes involved:
MainWindow.xaml - The main page containing the tab control.
MainWindow.xaml.cs - Code behind for above.
MainWindowViewModel.cs - View model for the above view, contains the collection.
Overview.xaml - User control that draws the overview tab item content.
OverviewViewModel.cs - View model for the above view.
Steps:
Replace the datatemplate in 'MainWindow.xaml' that draws the overview tab item with a blank user control named 'OverviewPlaceholder'
Make the reference to 'OverviewViewModel' public within 'MainWindowViewModel.cs'
Add a static reference to 'Overview' in 'MainWindow.xaml.cs'
Add an event handler to the loaded event of user control 'OverviewPlaceholder', within this method instantiate the static reference to 'Overview' only if it is null, set the datacontext of this reference to the 'OverviewViewModel' reference within the current datacontext (that is 'MainWindowViewModel') and set the place holder's content to be the static reference to 'Overview'.
Now the overview page is only drawn once because each time it is loaded (i.e. the user clicks onto the overview tab), it puts the already rendered, static user control back onto the page.
我有一个非常简单的解决方案来避免选项卡更改时选项卡重新加载,
在 tabItem 中使用 contentPresenter 而不是 content 属性。
例如(MVVM风格)
替换
经过
I have a really simple solution to avoid the tab reload on tab change,
use a contentPresenter in the tabItem instead of the content property.
e.g.(in MVVM style)
replace
by