【问题标题】:Should properties of ViewModels that implement INotifyPropertyChanged automatically update the data in DataGrid control when I update them?当我更新它们时,实现 INotifyPropertyChanged 的​​ ViewModel 的属性是否应该自动更新 DataGrid 控件中的数据?
【发布时间】:2010-07-23 16:53:27
【问题描述】:

我可能对 INotifyPropertyChanged 和 Silverlight 背后的目的感到困惑...

我有我在设计器中创建的 XAML:

<UserControl.Resources>
    <CollectionViewSource x:Key="theViewSource" d:DesignSource="{d:DesignInstance my:transferObject, CreateList=True}" />
</UserControl.Resources>

还有这个

            <Canvas DataContext="{StaticResource theViewSource}">
                <sdk:DataGrid ItemsSource="{Binding}" Name="theDataGrid">
                    <sdk:DataGrid.Columns>
                     <!-- columns omitted from post -->
                    </sdk:DataGrid.Columns>
                </sdk:DataGrid>
            </Canvas>

而且我还有一些代码隐藏:

Private Sub control_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    If Not (System.ComponentModel.DesignerProperties.GetIsInDesignMode(Me)) Then
        Dim myCollectionViewSource As System.Windows.Data.CollectionViewSource =
            CType(Me.Resources("theViewSource"), System.Windows.Data.CollectionViewSource)

        Dim myViewModel As New ViewModels.ViewModelThatHasAnObservableCollectionProperty()

        myCollectionViewSource.Source = myViewModel.TheObservableCollection()
    End If
End Sub

还有一个看起来像这样的 ViewModel:

Public Class ViewModelBase
    Implements ComponentModel.INotifyPropertyChanged

    Protected Sub RaisePropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

Public Class ViewModelThatHasAnObservableCollectionProperty
    Inherits ViewModelBase

    Public Sub RetrieveCollectionCompletedHandler(ByVal sender As Object, ByVal e As SilverlightConsumableService.RetrieveMyCollectionCompletedEventArgs)
        Dim unobservable As List(Of TransferObjects.TheTransferObject) = e.Result

        'I was hoping for this next line of code to force a refresh of the DataGrid
        TheObservableCollection = New ObservableCollection(Of TransferObjects.transferObject)(unobservable)
    End Sub

    Public Sub New()
        Dim theClient As New SilverlightConsumableService.SilverlightConsumableSoapClient

        AddHandler theClient.RetrieveMyCollectionCompleted, AddressOf RetrieveCollectionCompletedHandler

        theClient.RetrieveMyCollectionAsync()
    End Sub

    Private _theObservableCollection As ObservableCollection(Of TransferObjects.transferObject)
    Public Property TheObservableCollection() As ObservableCollection(Of TransferObjects.transferObject)
        Get
            Return _theObservableCollection
        End Get
        Set(ByVal value As ObservableCollection(Of TransferObjects.transferObject))
            _theObservableCollection = value
            RaisePropertyChanged("TheObservableCollection")
        End Set
    End Property
End Class

结果是 Silverlight 呈现数据网格时没有结果,因为事件处理程序尚未填充 TheObservableCollection。这是可以预料的。我希望在异步调用 Web 服务之后,调用 TheObservableCollection 的 Setter,随后调用 RaisePropertyChanged。

我的期望是 Silverlight 会通过将 dataGrid 重新绑定到属性来处理这个问题......使用 INotifyPropertyChanged 来实现它的目的不是为了让我不必以编程方式重新绑定网格,还是我对此感到困惑那个?

【问题讨论】:

    标签: silverlight-4.0 observablecollection inotifypropertychanged


    【解决方案1】:

    在 Silverlight(与 WPF 不同)中,您无需在服务响应处理程序中分配 ObservableCollection。这将破坏绑定。

    相反,清除已绑定的集合并使用服务响应中的项目重新填充它。更新集合将正确引发通知事件。如果您重新分配集合的引用,则与 UI 元素的绑定将被破坏。

    INotifyPropertyChanged 背后的目的是通知任何绑定成员该属性的 已更改。在集合的情况下,重新分配引用不计为值更改。更新集合成员的数量确实如此。同样,只要您调用 PropertyChanged 事件,更改单个属性就会引发通知事件。接口的目的是为 View 提供一个契约来监听 ViewModel。

    【讨论】:

    • 你是对的。如果我清除这些值并重新填充集合而不是使用 setter,它会按预期工作。谢谢!
    • 如果@j0rd4n 回答了您的问题,请记得标记它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2013-06-07
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多