1

я можно спутать о цели позади INotifyPropertyChanged и Silverlight ...Должны ли свойства ViewModels, реализующие INotifyPropertyChanged, автоматически обновлять данные в элементе управления DataGrid при их обновлении?

У меня есть код 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> 

И I также имеют некоторые коды:

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 

И V iewModel, который выглядит примерно так:

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 делает DataGrid без каких-либо результатов, поскольку TheObservableCollection не заполняется обработчиком события еще. Этого следовало ожидать. Я надеялся, что после асинхронного вызова веб-сервиса вызывается Setter для TheObservableCollection, а затем RaisePropertyChanged.

Мое предположение состояло в том, что Silverlight справлялся бы с этим, перебирая dataGrid для свойства ... Разве цель не заключается в использовании INotifyPropertyChanged, чтобы сделать это так, что мне не нужно повторно переустанавливать сетку или я смущен об этом?

ответ

1

В Silverlight (в отличие от WPF) вы не назначаете ObservableCollection в обработчике ответа службы. Это сломает привязку.

Вместо этого очистите уже привязанную коллекцию и повторно заполните ее элементами из вашего ответа службы. Обновление коллекции будет правильно поднять уведомления. Если вы повторно назначили ссылку коллекции, привязка к элементу пользовательского интерфейса будет нарушена.

Целью INotifyPropertyChanged является информирование всех связанных членов о том, что значение значения изменено. В случае коллекций повторное назначение ссылки не считается изменением значения. Обновление количества членов коллекции. Аналогично, изменение индивидуальных свойств приведет к появлению уведомлений, пока вы вызываете событие PropertyChanged. Целью интерфейса является предоставление контракта на просмотр для просмотра ViewModel.

+0

Вы правы. Если я очищу значения и заново заполняю коллекцию вместо использования setter, она работает так, как ожидалось. Благодаря! – Jason

+0

Если @ j0rd4n ответил на ваш вопрос, не забудьте отметить его как таковой. –