为什么我的ObservableCollection绑定控件跳转到第1项?

时间:2009-10-07 14:04:19

标签: c# data-binding user-controls mvvm

我有一个TDI,绑定到一个可观察的工作空间集合(全部基于Josh Smith的MVVM演示)。在一个选项卡上,有一个用户控件,也绑定到一个可观察的集合。如果我切换标签,用户控件总是跳回到第1项。

我有点绝望。我现在搜索了5个小时,但我无法弄清楚它为什么会这样做或在哪里搜索。

我尽可能地简化了整个事情并将其上传到:http://mad-scientists.co.uk/share/TestCandiMan.zip(约1.5MB)

非常感谢您的帮助!

我使用C#Express 2008。

1 个答案:

答案 0 :(得分:1)

这里的问题是每次选择另一个选项卡项时,TabControl都会为其内容实例化一个新的DataTemplate,因此会重新创建视图,并将所有设置设置为默认值。您必须实现一种机制,以便为给定的视图模型提供唯一的视图。如果没有MVVM,你只需要向ViewModel添加一个View属性,但这在很大程度上违背了MVVM的目的。

编辑以下注释:我的意思是每次切换标签时,TabControl都会使用DataTemplate中的新可视树显示其内容。

我们举一个例子:

  1. 您选择选项卡#1,其内容是CustomerViewModel。从DataTemplate创建一个新的可视化树(来自NewCustomerView)并显示在TabControl上。插入符号位于第一个文本框中,选项卡选择了第一个索引,等等。

  2. 您选择标签#2。选项卡#1中的内容不再存在于可视化树中并被丢弃。选项卡#2中的内容将遵循与构建树相同的过程。

  3. 您再次选择标签#1。来自选项卡#2的内容不再在可视树中并被丢弃。在这里,同样的机制再次激活。从DataTemplate构建了一个新的可视树,其中一切都是默认的。 Woops!但这是正常的,因为WPF的ContentPresenter不会将内容的树保留在内存中,因为每个可能的对象都是其内容的一次。

  4. =>理论上的解决方案,建立自己的视觉。例如,在一个完全不完美的世界中,在CustomViewModel中创建一个独特的NewCustomerView,并通过属性公开它,ley's's View。您将使用的新DataTemplate将是:

    <DataTemplate DataType="{x:Type CustomerViewModel}">
        <ContentPresenter Content="{Binding View}" />
    </DataTemplate>
    

    瞧,当从模板创建可视树时,演示者将是一个全新的,但视图是唯一的,不会被重新创建,因此插入符将位于用户离开它的同一位置,标签也一样。

    但是,就像我之前说过的那样,MVVM哲学并不是很好。尝试构建一个静态类,它能够为给定的ViewModel返回一个唯一的View,或类似的东西。

    另一个解决方案是将ViewModel添加到SelectedTabIndex之类的东西并绑定它们,CurrentFocusPosition等等,但这与我的视图完全相关。