WPF Problème avec la mise à jour de ObservableCollection<T> lié a un DataGrid
Bonjour a tous les sauveurs :mrgreen:
WPF, j'ai un Datagrid qui a des Colonnes prédéfinie en xaml. L'item source est lié une ObservableCollection<MaClass>.
XAML:
Code:
1 2 3 4 5 6 7 8 9
|
<DataGrid name="mondg"....>
<DataGrid.Columns>
<DataGridTextColumn Header="{DynamicResource rcol1}" Binding="{Binding col1}" MinWidth="60" />
<DataGridTextColumn Header="{DynamicResource rcol1}" Binding="{Binding col2}" MinWidth="60" />
<DataGridTextColumn Header="{DynamicResource rcol2}" Binding="{Binding col3}" MinWidth="60" />
</DataGrid.Columns>
</DataGrid> |
Code:
1 2 3 4 5 6 7 8 9
|
ObservableCollection<MaClass> collection= new ObservableCollection<MaClass>();
public MyWindow()
{
InitializeComponent();
mondg.ItemSource = collection;
} |
Donc j'ai besoin de mettre à jour la "collection" (ajout, modification, supp) et cela sur un Thread.
En utilisant le UI Thread(sans avoir a créer de thread)
Code:
1 2 3 4
|
//Sur "ClickEvent" d'un bouton par exemple:
collection.add(new MaClass(){col1="val1",col2="val2",col3="val3"});
mondg.items.refresh(); |
Les valeur s'affiche :). Mais en utilisant un thread j'ai l'exception: Ce type de collection ne prend pas en charge les modification de son SourceCollection à partir d'un thread différent du thread du Dispatcher.
C'est tout à fait normal, donc j'ai fai appel un au dispatcher et utiliser une collection qui fait appel au dispatcher comme suit:
Code:
1 2 3
|
MaClass mc = new MaClass(){col1="val1",col2="val2",col3="val3"};
Application.Current.Dispatcher.Invoke(new Action(() => {mondg.Add(mc); })); |
J'ai u l'exeption: ArrgumentExceptionWasUnhadled: Création obligatoire de DependencySource sur le même Thread que le DependencyObject.
Idem pour en utilisant la classe MTObservableCollection:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
public class MTObservableCollection<T>:ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
var eh = CollectionChanged;
if (eh != null)
{
Dispatcher dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
let dpo = nh.Target as DispatcherObject
where dpo != null
select dpo.Dispatcher).FirstOrDefault();
if (dispatcher != null && dispatcher.CheckAccess() == false)
{
dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
}
else
{
foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
nh.Invoke(this, e);
}
}
}
} |