【发布时间】:2014-08-30 12:00:10
【问题描述】:
在 Prism、MVVM、Windows 8.1 StoreApp 中,我希望 ViewModel 捕获 ListView 中的 SelectItem。 ListView 包含一个 ObservableCollection 对象。 ViewModel 需要查找所选对象的更多详细信息并通知 View。视图应依次显示对象的详细信息。
我已经实现了这个,但是视图总是显示以前的对象(在选择一个新对象之后)
当然,我正在寻找的是在选择对象时视图中的即时且正确的反应。这是我的coden-ps,都是VB代码。
编辑:我已经提出了另一个 - 较小的例子,使用这种方法。我记录了这个过程in this video.请在阅读之前先看看!!
对象来自 ViewModel:
Public Property Persons 作为新的 ObservableCollection(Of Person)
它们被绑定到一个用户控件:
<Grid>
<ListView
ItemsSource="{Binding Persons}"
ItemTemplate="{StaticResource BusinessCard}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Behaviors:ListViewSelectionChangedAction/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListView>
</Grid>
通过 Behavior 最终通过以下代码在 ViewModel 中结束:
Sub New(InjectedEventAggregator As IEventAggregator)
LocalEventAggregator = InjectedEventAggregator
LocalEventAggregator.GetEvent(Of PersonIsSelectedEvent)().Subscribe(AddressOf HandlePersonIsSelected, True)
这个事件由这个例程处理
Public Sub HandlePersonIsSelected(ByVal SelectedPerson As Person)
ActualPerson = SelectedPerson
End Sub
所有这一切的最后一部分是包含 ActualPerson 的属性,如下所示:
Private Property _ActualPerson As Person
Public Property ActualPerson As Person
Get
Return _ActualPerson
End Get
Set(value As Person)
SetProperty(_ActualPerson, value)
End Set
End Property
编辑: 这是应显示所选 ActualPerson 的 XAML:
<StackPanel DataContext="{Binding ActualPerson}" >
<Image Source="{Binding Photo}" Stretch="Fill" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text="{Binding FamilyName}" />
<TextBlock Text="{Binding Gender}" />
</StackPanel>
</StackPanel>
当我单步执行代码时,我可以看到 ViewModel 中捕获了 SelectedItem 事件,调用了所选人员的处理程序,更新了属性。使用 Prism 这也意味着触发 NotifyPropertyChanged 事件。它确实被解雇了,否则我猜前一个对象也不会显示。
但是为什么视图没有立即用正确的(人)对象更新?
如果你有线索....做我的贵宾!
问候
【问题讨论】:
-
您尚未显示“视图应依次显示对象的详细信息”的代码。如果 XAML 代码绑定到 ActualPerson 对象,它应该显示 ActualPerson 的详细信息。您可以尝试将 TextBlock 的 Text 属性绑定到 ActualPerson.
并检查您所看到的内容。 -
@Wonderfulworld 感谢您的反应。我在原始帖子中进行了编辑。从列表视图中选择的对象是一个人。基于此,将刷新 ActualPerson 属性。问题不在于绑定本身,而在于时机:只有前一个对象被完全显示。绑定到其他属性有效,但反应滞后:始终是上次单击时选择的对象。
-
您的代码在我看来是正确的。只要调用了“ActualPerson = SelectedPerson”,UI 就会更新。除非 ActualPerson 是以前的对象,否则您应该会看到最近点击的人。在 ActualPerson 的 Set 操作里面放一个断点,看它是否被调用了两次,是否有人将最新的对象设置回之前的对象。
-
@wonderfulworld 感谢您的回复。我完全同意你的观点,代码看起来不错,但这正是我的问题!!我不明白为什么它不能正常工作。按照你的建议,我已经在二传手上休息了一下,并看到它通过了一次。更进一步,Prism 库函数接管(通过 SetProperty),我可以确保 BindableBase 类引发 PropertyChanged。仍然……对视图没有反应。
标签: vb.net mvvm windows-store-apps prism inotifypropertychanged