5

私はMVVM WPFアプリを設計しており、CustomerタイプのSelectedCustomerというプロパティを持つViewModelを持っています。このオブジェクトには、ObservableCollection 型の SummaryDetails というプロパティがあり、行ごとに ListView にレンダリングされます。

これを行うために、ViewModel に CustomerSummaryDetails という別のプロパティを作成しました。このプロパティには、上記の顧客に含まれるコレクションを返す get のみが含まれています。

XAML で、ItemsSource を CustomerSummaryDetails プロパティにバインドしました。

これは、きれいではない SelectedCustomer.SummaryDetails にバインドする必要がなかったためです。

SelectedCustomer プロパティには get メソッドと set メソッドがあり、set は OTHER プロパティ CustomerSummaryDetails に対して OnPropertyChanged を呼び出し、基になるコレクションが変更され、更新することを XAML に知らせます。

問題は、コレクション内のアイテムを更新すると、適切なイベントがすべて呼び出されているにもかかわらず、GUI に反映されないことです。私は介入し、SelectedCustomer の set メソッドが呼び出されました。次に、OnPropertyChanged("CustomerSummaryDetails") 呼び出しに従います。これは、期待どおり CustomerSummaryDetails プロパティの「get」メソッドに入ります。この時点で返されたコレクションの値を掘り下げました。リスト内の値は更新された値ですが、GUI には何も反映されていないため、GUI が get メソッドを呼び出して更新しているように見えて困惑しています。 OnPropertyChanged() 呼び出しでそれが、視覚的に反映されていません。

更新 - コードが含まれています

コードが含まれていないことをお詫びします。説明する方が簡単だと思いましたが、ViewModel の主なプロパティは次のとおりです。

public CustomerSummaryViewModel SelectedCustomer
{
    get { return _selectedCustomer; }
    set
    {
        _selectedCustomer = value;
        OnPropertyChanged("CustomerSummaryDetails");
    }
}

public ObservableCollection<RbcUICustomerSummary> CustomerSummaryDetails
{
    get { return _selectedCustomer.SummaryDetails; }
}

public ItemSummaryViewModel SelectedItem
{
    get { return _selectedItem; }
    set
    {
        _selectedItem = value;
        OnPropertyChanged("SelectedItem");
    }
}

以下の XAML

    <ListView x:Name="lvCustomerSummary" Margin="10,10,10,10" Background="#F4F8FB" ItemsSource="{Binding CustomerSummaryDetails}" MouseDoubleClick="lvCustomerSummary_MouseDoubleClick" ItemContainerStyle="{StaticResource myHeaderStyleColor}" VirtualizingStackPanel.IsVirtualizing="False" VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ListView.View>
            <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
                    <GridView.Columns>
                    <GridViewColumn Header=""  >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate >
                                <Grid>
                                    <Image Source="{z:ImageStaticResource {Binding IconSelect}}" Width="20" Height="20" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="200" Header="SubCustType" DisplayMemberBinding="{Binding SubCustType}" >
                    </GridViewColumn>
                    <GridViewColumn Width="200" Header="SubCustValue"  DisplayMemberBinding="{Binding SubCustValue}">
                    </GridViewColumn>
                    <GridViewColumn Header=""  >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate >
                                <Grid>
                                    <Image Source="{z:ImageStaticResource {Binding IconFlag}}" Width="20" Height="20" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

最後に、実際の更新を行う Updater メソッド

private void DisplayCustomerComment(string commentEnt)
{            
    if (_queueViewModel.SelectedCustomer == null) return;
        var selCust = _queueViewModel.SelectedCustomer;

    foreach (var t in selCust.SummaryDetails
        .Where(t => t.SubCustType == AppString.CustomerSummary.Comment))
    {
        t.SubCustValue = commentEnt;
        break;
    }

    _queueViewModel.SelectedCustomer = selCust;
}
4

1 に答える 1

23

ObservableCollection 自体 (アイテムの追加/削除など) を変更するのではなく、そのコレクション内のアイテムを変更します。ObservableCollection は、アイテムに関する変更ではなく、独自の変更を通知する責任があります。SubCustValue のセッターで NotifyPropertyChange("SubCustValue") を使用する必要があります。

個々のアイテムの個々のプロパティではなく、コレクション全体を NotifyPropertyChange() すると、WPF は実際には同じインスタンス (同じコレクションへの同じオブジェクト参照) であることを検出するため、変更は UI に反映されません。だから何も変わっていないようです。

于 2012-10-31T19:53:05.137 に答える