Bonjour a tous les sauveurs

WPF, j'ai un Datagrid qui a des Colonnes prédéfinie en xaml. L'item source est lié une ObservableCollection<MaClass>.

XAML:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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);
                }
            }
        }
    }