2010-07-02 11 views
5

Devo integrare un'interfaccia utente WPF in un'applicazione .NET 2.0.Interoperabilità tra System.Windows.Forms.Application e System.Windows.Application

ObservableCollection deve essere modificato nel thread GUI Dispatcher, così mi si avvicinò con una soluzione che comprenda InvokeLater()

ObservableCollection<Item> items; 
public delegate void AddItemDelegate(Item i); 

public void AddItem(Item item) 
{ 
    System.Windows.Application.Current.Dispatcher.BeginInvoke(
     new AddItemsDelegate(i => items.Add(i), item); 
} 

Tuttavia, dal momento che il progetto è stato originariamente scritto con .NET 2.0, il thread principale utilizza un System.Windows.Forms.Application , quindi System.Windows.Application.Current è nullo.

Non posso sostituire l'attuale System.Windows.Forms.Application con un System.Windows.Application dato che la mia applicazione si basa fortemente su questa API e le due classi sono ampiamente incompatibili.

C'è un modo per ottenere l'attuale System.Windows.Application? O un modo per chiamare BeginInvoke() sul mio System.Windows.Forms.Application? Oppure ho pensato di scrivere il mio sistema fai-da-te per delegare l'edizione della collezione dal thread corretto?

risposta

5

È necessario salvare un riferimento a SynchronizationContext.Current dal thread dell'interfaccia utente (magari in una proprietà statica) e utilizzarlo al posto dello Dispatcher.

In WPF, questo restituirà un DispatcherSynchronizationContext; in WinForms, restituirà un valore WindowsFormsSynchronizationContext.

È quindi possibile chiamare Post sullo SynchronizationContext salvato, che equivale a BeginInvoke.

Problemi correlati