0

项目:一个带有“便利贴”信息的小布告栏。VB.Net,VS2013,Windows 8.1 桌面。棱镜/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">

此外,笔记使用“便利贴”模板呈现,定义为:

<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>

最后是带有 ItemsSource 和模板属性的 GridView:

<GridView x:Name="grdMessages"
   ItemsSource="{Binding Messages}"
   ItemTemplate="{StaticResource PostIt}"/>

到目前为止,对于视图中的演示文稿的 XAML。代码隐藏只不过是一个带有初始化的简单构造函数,它看起来像:

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。

当我单步执行代码时,我看到消息到达和 Set,因此调用了 SetProperty。

但是 Messages 没有显示在 View 上。在我看来,当检索到消息时,视图没有收到更改通知。

这种方法有什么问题?

4

1 回答 1

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 的绑定对象。

于 2014-09-05T11:33:32.200 回答