项目:带有“post-it”消息的小型公告板。 VB.Net,VS2013,Windows 8.1桌面。 Prism / MVVM。
问题:当属性发生变化时,NotifyPropertyChanged事件似乎根本不会触发。消息不会显示在布告栏上。
问题:为什么会这样?或者:下面的代码出了什么问题?
代码:
首先,我们有视图。它定义如下:
<prism:VisualStateAwarePage
x:Name="pageRoot"
x:Class="MemoBoard.Views.BoardPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="using:Microsoft.Practices.Prism.StoreApps"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
此外,笔记使用“Post-it”模板呈现,定义为:
<prism:VisualStateAwarePage.Resources>
<DataTemplate x:Name="PostIt">
<Grid Width="250" Height="250" >
<TextBlock
FontFamily="Buxton Sketch"
Text="{Binding Text}"
FontSize="20"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="20,40,50,0"
TextWrapping="WrapWholeWords">
</TextBlock>
</Grid>
</DataTemplate>
</prism:VisualStateAwarePage.Resources>
最后是GridView,其中包含ItemsSource和Template的属性:
<GridView x:Name="grdMessages"
ItemsSource="{Binding Messages}"
ItemTemplate="{StaticResource PostIt}"/>
到目前为止,XAML用于View中的演示。代码隐藏只不过是一个带有Initialization的简单构造函数,它看起来像:
Namespace Views
Public NotInheritable Class BoardPage
Inherits VisualStateAwarePage
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
这一切都非常简单,幸好使用Prism库来获得更丰富的功能。下一部分是ViewModel,Viewmodel也很简单,不在书中。 它看起来像:
Namespace ViewModels
Public Class BoardPageViewModel
Inherits ViewModel
Private _MessageRepository As IMessageRepository
Private Property _Messages As ObservableCollection(Of Message)
Public Property Messages As ObservableCollection(Of Message)
Get
Return _Messages
End Get
Set(value As ObservableCollection(Of Message))
SetProperty(_Messages, value)
End Set
End Property
Public Overrides Async Sub OnNavigatedTo(navigationParameter As Object, navigationMode As NavigationMode, viewModelState As Dictionary(Of String, Object))
MyBase.OnNavigatedTo(navigationParameter, navigationMode, viewModelState)
_MessageRepository = New MessageRepository
Messages = Await _MessageRepository.GetMessagesAsync()
End Sub
End Class
End Namespace
通过作为存储库一部分的WebAPI检索消息,我确信它工作正常。正确读取项目并将其传递给ViewModel。
当我单步执行代码时,我看到Messages到达和Set,因此调用了SetProperty。
但消息未显示在视图上。在我看来,当检索到消息时,View不会收到有关更改的通知。
这种方法有什么问题?
答案 0 :(得分:0)
问题不在于方法,而在于_Messages集合的本地版本不应该声明为私有(属性),而应该声明为局部变量。因此,声明属性和本地版本的完整声明应如下所示:
Dim _Messages As ObservableCollection(Of Message)
Public Property Messages As ObservableCollection(Of Message)
Get
Return _Messages
End Get
Set(value As ObservableCollection(Of Message))
SetProperty(_Messages, value)
End Set
End Property
现在,SetProperty将触发事件,正确的值将传递给ViewModel的绑定对象。