我有一个TDI,绑定到一个可观察的工作空间集合(全部基于Josh Smith的MVVM演示)。在一个选项卡上,有一个用户控件,也绑定到一个可观察的集合。如果我切换标签,用户控件总是跳回到第1项。
我有点绝望。我现在搜索了5个小时,但我无法弄清楚它为什么会这样做或在哪里搜索。
我尽可能地简化了整个事情并将其上传到:http://mad-scientists.co.uk/share/TestCandiMan.zip(约1.5MB)
非常感谢您的帮助!
我使用C#Express 2008。
答案 0 :(得分:1)
这里的问题是每次选择另一个选项卡项时,TabControl都会为其内容实例化一个新的DataTemplate,因此会重新创建视图,并将所有设置设置为默认值。您必须实现一种机制,以便为给定的视图模型提供唯一的视图。如果没有MVVM,你只需要向ViewModel添加一个View属性,但这在很大程度上违背了MVVM的目的。
编辑以下注释:我的意思是每次切换标签时,TabControl都会使用DataTemplate中的新可视树显示其内容。
我们举一个例子:
您选择选项卡#1,其内容是CustomerViewModel。从DataTemplate创建一个新的可视化树(来自NewCustomerView)并显示在TabControl上。插入符号位于第一个文本框中,选项卡选择了第一个索引,等等。
您选择标签#2。选项卡#1中的内容不再存在于可视化树中并被丢弃。选项卡#2中的内容将遵循与构建树相同的过程。
您再次选择标签#1。来自选项卡#2的内容不再在可视树中并被丢弃。在这里,同样的机制再次激活。从DataTemplate构建了一个新的可视树,其中一切都是默认的。 Woops!但这是正常的,因为WPF的ContentPresenter不会将内容的树保留在内存中,因为每个可能的对象都是其内容的一次。
=>理论上的解决方案,建立自己的视觉。例如,在一个完全不完美的世界中,在CustomViewModel中创建一个独特的NewCustomerView,并通过属性公开它,ley's's View。您将使用的新DataTemplate将是:
<DataTemplate DataType="{x:Type CustomerViewModel}">
<ContentPresenter Content="{Binding View}" />
</DataTemplate>
瞧,当从模板创建可视树时,演示者将是一个全新的,但视图是唯一的,不会被重新创建,因此插入符将位于用户离开它的同一位置,标签也一样。
但是,就像我之前说过的那样,MVVM哲学并不是很好。尝试构建一个静态类,它能够为给定的ViewModel返回一个唯一的View,或类似的东西。
另一个解决方案是将ViewModel添加到SelectedTabIndex之类的东西并绑定它们,CurrentFocusPosition等等,但这与我的视图完全相关。