在下面的代码中,我无法从异步调用中更新WPF Window
。所有显示的都是“第一项”。问题是Window
不是从WPF应用程序启动的,而是从类模块启动的。由于我们的主UI应用程序是VB6应用程序,它通过调用Com visible Net dll来启动som WPF元素。这种方法效果很好,但下面不是这样。
主要控制台应用
Imports Window
Imports System.Windows
Imports System.Threading
Module Module1
Sub Main()
Dim launcher As New WindowLauncher
launcher.LaunchWindow()
Console.WriteLine("Press a key to continue...")
Console.ReadLine()
End Sub
End Module
WPF WINDOW LAUNCHER
Imports Window
Public Class WindowLauncher
Public Sub LaunchWindow()
Dim model As New ViewModel
Dim window As New DisplayWindow
model.Dispatcher = window.Dispatcher
window.DataContext = model
window.Show()
model.Collection.Add("Second item.")
model.StartAddingItems()
'window.Close()
End Sub
End Class
WPF用户控制图书馆项目中的WPF窗口及其视图模式
<Window x:Class="DisplayWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DisplayWindow" Height="300" Width="300">
<Grid>
<ListBox ItemsSource="{Binding Collection}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Imports System.Collections.ObjectModel
Imports System.Threading
Imports System.Windows.Threading
Public Class ViewModel
Public Sub New()
Collection = New ObservableCollection(Of String)
Collection.Add("First item")
End Sub
Public Property Collection As ObservableCollection(Of String)
Public Property Dispatcher As Dispatcher
Public Sub StartAddingItems()
Dim progress As New Progress(Of String)
AddHandler progress.ProgressChanged, AddressOf ProgressChanged
For i = 1 To 10
DoSomething(progress).Wait()
Next
End Sub
Private _counter As Integer
Private Async Function DoSomething(progress As IProgress(Of String)) As Task
Await Task.Delay(10 * _counter)
_counter += 1
progress.Report(CStr(_counter))
End Function
Private Sub ProgressChanged(sender As Object, e As Object)
Dim text = CStr(e)
Me.Dispatcher.BeginInvoke(Sub() AddToCollection(text), DispatcherPriority.Background)
'The challenge seems to be to find the correct Dispatcher. Now the property is set from the WPF Window, but the code never reaches the AddToCollection method. `
AddToCollection(text)
`This call throws the well known "This type of CollectionView does not support changes..." exception.`
End Sub
Private Sub AddToCollection(text As String)
Collection.Add(String.Format("item {0}", text))
End Sub
End Class
答案 0 :(得分:0)
问题出在以下几个电话中:
model.Collection.Add("Second item.")
model.StartAddingItems()
这似乎阻止了对用户界面的更新。
我将这些调用移动到了窗口。WPF.Form的加载事件(表单保存了对viewmodel的引用),并将viewmodel&#39; s Dispatcher
设置为那里的窗口。 / p>
答案 1 :(得分:0)
如果你正在显示WPF窗口,你真的需要一个单独的WPF线程(带有一个STA主循环):
var thread = new Thread(() =>
{
var application = new Application();
application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();