1

MVVM パターンを使用して WPF でデータバインディングを使用しようとしています。これまでのところ、すべてが適切に組み立てられており、適切なタイプのクラスとオブジェクトを使用しているようです。監視可能なコレクションは初めて正しく読み込まれますが、データグリッドが変更されたときに更新されません。Observable Collections は自動的に INPC を実装する必要があり、基本クラスでそのハンドラーも提供しているため、なぜまだ機能せず、UI を更新しないのか混乱しています。以下は私のコードです:

ViewModelBase クラス:

#Region "INotifyPropertyChanged Members"
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
    VerifyPropertyName(propertyName)
    Dim handler As PropertyChangedEventHandler = PropertyChangedEvent
    If handler IsNot Nothing Then
        Dim e = New PropertyChangedEventArgs(propertyName)
        handler(Me, e)
    End If
End Sub
#End Region

MainWindowViewModel クラス:

Public Class MainWindowViewModel
    Inherits ViewModelBase

    Private Shared _coreInfoData As ObservableCollection(Of Person)
    Public Shared Property CoreInfoData() As ObservableCollection(Of Person)
        Get
            Return _coreInfoData
        End Get
        Set(ByVal value As ObservableCollection(Of Person))
            _coreInfoData = value
        End Set

    Public Sub Main()
        If CoreInfoData IsNot Nothing Then
            CoreInfoData.Clear()
        End If
        CoreInfoData = GetRecords()
    End Sub

GetRecords 関数は、利用可能な最新のレコード セットを取得するデータベースへの呼び出しです。

私の見解では、実際には CollectionViewSource にバインドし、それをデータグリッドにバインドしています。

<UserControl.Resources>
    <CollectionViewSource Source="{Binding Path=CoreInfoData, Mode=TwoWay}" x:Key="cvs">
        <CollectionViewSource.GroupDescriptions>
            <dat:PropertyGroupDescription PropertyName="GroupId"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource cvs}}" AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" IsReadOnly="True" />
        <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" IsReadOnly="True"/>
    </DataGrid.Columns>
</DataGrid>

クラスにはPersonプロパティLastNameFirstName(とりわけ)があります。私が理解しているように、ObservableCollection自体が変更された場合-クリアして元に戻すことで行うことのように、INPCイベントが自動的に発生するはずですが、DataGridは2回目に更新されないようです. どんなアイデアでも本当に役に立ちます。

ありがとう!

*編集* 問題を解決する方法は次のとおりです。

Public Shared Property CoreInfoData() As ObservableCollection(Of Person)

Public Shared Property CoreInfoData() As ObservableCollection(Of Person)
    Get
        Return _coreInfoData
    End Get
    Set(ByVal value As ObservableCollection(Of Person))
        If _coreInfoData Is Nothing Then
            'get data
             _coreInfoData = value
        Else
             'refresh data
             _coreInfoData.Clear()
              For i = 0 To value.Count - 1
                    _coreInfoData.Add(value(i))
              Next
        End If
    End Set
End Property

Set メソッドが初めて呼び出されると、新しい _coreInfoData 変数が作成されます。後続の呼び出しは、コンテンツ全体をクリアし、各アイテムをループしてコレクションに追加することにより、既存のアイテムを置き換えます。Clemens、Dan Busha、Charleh (およびその他) の有益なコメントに感謝します。

4

4 に答える 4

3

プロパティのタイプが であるため、PropertyChanged イベントが自動的に発生することはありませんObservableCollection。セッターでそれを上げる必要があります:

Set(ByVal value As ObservableCollection(Of Person)) 
    _coreInfoData = value
    OnPropertyChanged("CoreInfoData")
End Set 
于 2012-08-07T13:40:13.307 に答える
2

INotifyPropertyChangedINotifyCollectionChangedを混同しています。

ObservableCollection は INotifyPropertyChanged を実装します。これは、Count やインデクサー Item[] などのプロパティのイベントを発生させるために使用されます。実現するために必要な機能には拡張されません。

于 2012-08-07T14:11:34.587 に答える
2

ObservableCollection に値を割り当てているように見えますが、これはコレクションを変更せず、それを置き換えます。CoreInfoData プロパティの PropertyChanged イベントを発生させるか、set値から項目を 1 つずつ ObservableCollection に追加します (ObservableCollection は PropertyChanged イベントの発生を管理する必要があります)。

于 2012-08-07T13:45:51.587 に答える
1

最初に-なぜあなたのコレクションは共有/静的なのですか?

ObservableColelctionを使用する場合、通常はインスタンスを1回だけ作成し、clear、add、removeを使用します。

セッターで行ったように新しいインスタンスを設定する場合は、OnPropertyChanged( "CoreInfoData")も呼び出す必要があります。

しかし、私は明確にして追加したいと思います

    CoreInfoData.Clear()
    CoreInfoData.AddRange(GetRecords())
于 2012-08-07T13:48:09.233 に答える