Évolution objet collectionviewsource Source dans un MVVM monde
Édité: j'ai créé un nouveau VS2010 WPF appilication avec seulement 3 fichiers MainWindow.xaml, MainWindow.xaml.cs, et MainWindowViewModel.cs (Énumérés ci-Dessous). Si quelqu'un se sent vraiment utile vous pouvez reproduire le problème en quelques secondes (copier/coller). Lorsque vous exécutez l'application, le contrôle DataGrid affiche la chaîne "OldCollection" ce qui est faux. Si vous modifiez le ItemsSource de liaison à MyCollection, il affiche "NewCollection" ce qui est correct.
Description Complète:
Au début, j'avais un DataGrid avec son ItemsSource lié à MyCollection. J'ai/besoin d'une méthode UpdateCollection qui assigne une nouvelle ObservableCollection<> MyCollection. Avec l'ajout de NotifyPropertyChange à MyCollection l'INTERFACE utilisateur des mises à jour.
Ensuite, il est devenu nécessaire d'introduire un objet collectionviewsource pour permettre le regroupement. Avec l'INTERFACE utilisateur lié à MyCollectionView, les appels à UpdateCollection maintenant n'ont aucun effet. Le débogueur confirme que MyCollectionView contient toujours la première MyCollection. Comment puis-je obtenir mon NewCollection être reflétée dans la Vue? J'ai essayé de Vue.Refresh(), la Liaison objet collectionviewsource, et d'innombrables autres stratégies.
Remarque: Principalement les autres sont concernés par les modifications apportées à la Collecte d'éléments à ne pas la mise à jour de la vue (regroupement/tri) sans faire appel à Actualiser. Mon problème est que je suis l'affectation d'une toute nouvelle collection pour objet collectionviewsource et la vue/UI ne change jamais.
//MainWindow.xaml
<Window x:Class="CollectionView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="grid" ItemsSource="{Binding MyCollectionView}" />
</Grid>
</Window>
//MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace CollectionView
{
///<summary>
///Interaction logic for MainWindow.xaml
///</summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
}
//MainWindowViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;
namespace CollectionView
{
class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "OldCollection" } };
MyCollectionViewSource = new CollectionViewSource();
//Bind CollectionViewSource.Source to MyCollection
Binding MyBind = new Binding() { Source = MyCollection };
BindingOperations.SetBinding(MyCollectionViewSource, CollectionViewSource.SourceProperty, MyBind);
//The DataGrid is bound to this ICollectionView
MyCollectionView = MyCollectionViewSource.View;
//This assignment here to demonstrate that View/UI does not update to show "NewCollection"
MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "NewCollection" } };
}
//Collection Property
//NotifyPropertyChanged added specifically to notify of MyCollection re-assignment
ObservableCollection<MyObject> _MyCollection;
public ObservableCollection<MyObject> MyCollection
{
get { return _MyCollection; }
set
{
if (value != _MyCollection)
{
_MyCollection = value;
NotifyPropertyChanged("MyCollection");
}
}
}
public CollectionViewSource MyCollectionViewSource { get; private set; }
public ICollectionView MyCollectionView { get; private set; }
//Method updates MyCollection itself (Called via ICommand from another ViewModel)
public void UpdateCollection(ObservableCollection<MyObject> NewCollection)
{
MyCollection = NewCollection;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
class MyObject
{
public string TestString { get; set; }
}
}
Merci,
OriginalL'auteur aidesigner | 2012-04-10
Vous devez vous connecter pour publier un commentaire.
Je voudrais choisir l'une des deux solutions suivantes.
Tout d'abord, vous pouvez prendre votre
ObservableCollection
et de créer unICollectionView
(regroupement, de tri) une fois. Au lieu de remplacer leObservableCollection
vous pouvez utiliser.Clear()
et d'ajouter les articles de la nouvelle Collection. Cela a le bonus supplémentaire de ne pas briser votre regroupement et de tri.Deuxième approche: à chaque fois que vous remplacez votre
ObservableCollection
vous devez créer un nouveauICollectionView
pour le tri et le regroupement.Vous pouvez simplement lier à votre collection, si vous prenez le DefaultView
et vous pouvez jeter votre objet collectionviewsource code de liaison des trucs.
OriginalL'auteur blindmeis
Le problème est certainement le fait que vous n'êtes pas de liaison à la source de votre MyCollection de la propriété, vous êtes à l'attribution d'une fois et il n'est jamais mis à jour à nouveau.
Vous devriez faire quelque chose comme ce qui suit:
Je m'excuse si le ci-dessus ne fonctionne pas tout de suite, sans tordre - c'est généralement le genre de chose que j'ai mis en place dans le code xaml, car il est beaucoup plus facile.
Voir Aussi: Comment puis-je changer la liaison d'un CollectionView.Source?
OriginalL'auteur Alain
Le fait que la liaison n'est pas le travail, c'est incroyablement bizarre. J'ai rencontré exactement le même problème avec le Xceed DataGridCollectionViewSource - mais j'ai supposé que c'était parce que Xceed a été foiré.
Ma solution a été de créer une nouvelle marque DataGridCollectionViewSource à chaque fois que la collection sous-jacente a été remplacé, et de le reconfigurer en programmant, et ensuite mettre à jour le myDataGrid.Propriété de la Source au point de la nouvelle DataGridCollectionViewSource. Cette solution de contournement ne sera certainement de travail, mais qui va à l'encontre de l'objectif de liaisons, qui doit être au travail:
Peut-être cette force brute solution pour résoudre votre problème? Je comprends si vous ne voulez même pas à considérer cela encore, car il est tellement sale.
OriginalL'auteur Alain