2

ListBox から項目を削除しようとしています。コマンドは適切に起動され、アイテムはデータベースから正しく削除されますが、リストは更新されません。

ここにビューモデルがあります。私はMVVM Light 4.1を使用しています

public class ViewAllViewModel : ViewModelBase
{
    public ViewAllViewModel()
    {
        NavigateToAddNew = new RelayCommand(() => NavigationController<Views>.Current.NavigateTo(Views.AddNew));
        Remove = new RelayCommand<int>(DeleteMeasure);

        using (var repository = App.ServiceLocator.Get<IRepository>())
        {
            Measures = new ObservableCollection<Measure>(repository.Measures);
        }
    }

    private void DeleteMeasure(int measureId)
    {
        Measure measure;

        using (IRepository repository = App.ServiceLocator.Get<IRepository>())
        {
            measure = repository.Measures.Single(m => m.Id == measureId);
            repository.Measures.Delete(measure);
            repository.SaveChanges();
        }

        measure = Measures.Single(m => m.Id == measureId);
        if (Measures.Remove(measure))
        {
            RaisePropertyChanged(() => Measures);
        }
    }

    public RelayCommand NavigateToAddNew { get; set; }
    public RelayCommand<int> Remove { get; set; }

    private ObservableCollection<Measure> _measures;
    public ObservableCollection<Measure> Measures
    {
        get { return _measures; }
        set { Set(() => Measures, ref _measures, value); }
    }
}

助けてくれてありがとう。

PS:同様の質問があることは知っていますが、受け入れられた回答はどれもうまくいきませんでした:(

編集 1 これは、ListBox を項目のリストにバインドするために XAML ページで使用するコードです。

<ListBox Grid.Row="1" DataContext="{Binding Path=Measures}" ItemsSource="{Binding}" />

ここにViewModelのメインコンテナへのバインディングがあります

<Grid DataContext="{Binding Source={StaticResource Locator}, Path=ViewAll}" x:Name="LayoutRoot" />

EDIT 2 これは ViewModel の完全なコードです

public class ViewAllViewModel : ViewModelBase
{
    public ViewAllViewModel()
    {
        NavigateToAddNew = new RelayCommand(() => NavigationController<Views>.Current.NavigateTo(Views.AddNew));
        Remove = new RelayCommand<int>(DeleteMeasure);

        LoadMeasures();

        Messenger.Default.Register<PropertyChangedMessage<ObservableCollection<Measure>>>(this, message => LoadMeasures());
    }

    private void LoadMeasures()
    {
        using (var repository = App.ServiceLocator.Get<IRepository>())
        {
            Measures = new ObservableCollection<Measure>(repository.Measures.OrderByDescending(m => m.MeasureDate).ThenByDescending(m => m.Id).Take(20));
        }
    }

    private void DeleteMeasure(int measureId)
    {
        Measure measure;

        using (IRepository repository = App.ServiceLocator.Get<IRepository>())
        {
            measure = repository.Measures.Single(m => m.Id == measureId);
            repository.Measures.Delete(measure);
            repository.SaveChanges();
        }

        measure = Measures.Single(m => m.Id == measureId);
        Measures.Remove(measure);

        RaisePropertyChanged("LastMeasure", null, measure, true);
    }

    public RelayCommand NavigateToAddNew { get; set; }
    public RelayCommand<int> Remove { get; set; }

    private ObservableCollection<Measure> _measures;
    public ObservableCollection<Measure> Measures
    {
        get { return _measures; }
        set { Set(() => Measures, ref _measures, value); }
    }
}
4

1 に答える 1

1

明らかに間違っているものは何もありません。私が提案できるのは、これを単純化するListBoxことだけです。

<ListBox Grid.Row="1" ItemsSource="{Binding Path=Measures}" />

そして、呼び出すコードを削除しますRaisePropertyChanged(() => Measures);(必要ないため)。

Measuresどちらも機能しない場合は、次のように、プロパティを完全にリセットするとどうなるかをテストします。

private void DeleteMeasure(int measureId)
{
    using (IRepository repository = App.ServiceLocator.Get<IRepository>())
    {
        var measure = repository.Measures.Single(m => m.Id == measureId);
        repository.Measures.Delete(measure);
        repository.SaveChanges();
    }

    Measures = repository.Measures;
}

これにより のリフレッシュが成功した場合、ListBoxで何かが起こっていることを意味しObservableCollectionます。

于 2012-07-04T22:23:34.987 に答える