View层两个控件:ListBox展示数据,Add按钮点击以后添加一行数据:
<ListBox Margin="50" ItemsSource="{Binding TestCollection}"></ListBox>
<Button x:Name="button" Content="ADD" Command="{Binding AddCommand}" HorizontalAlignment="Left" Margin="625,393,0,0" VerticalAlignment="Top" Width="75"/>
ViewModel层:
public class MainFormVM
{
public ObservableCollection<string> TestCollection { get; set; } = new ObservableCollection<string>() { "~", "~" };
public ICommand AddCommand
{
get
{
return new RelayCommand(() =>
{
AddData();
});
}
}
private void AddData()
{
TestCollection.Add("~");
}
}
以上代码执行之后没有任何问题但是当我们用另一个线程执行AddData方法时:
public ICommand AddCommand
{
get
{
return new RelayCommand(() =>
{
Thread t = new Thread(AddData);
t.Start();
});
}
}
会出现异常:System.NotSupportedException:“该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。
解决办法:
public class MainFormVM
{
public ObservableCollection<string> TestCollection { get; set; } = new ObservableCollection<string>() { "~", "~" };
private Dispatcher m_Dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
public ICommand AddCommand
{
get
{
return new RelayCommand(() =>
{
Thread t = new Thread(AddData);
t.Start();
});
}
}
private void AddData()
{
m_Dispatcher.Invoke(() =>
{
TestCollection.Add("~");
});
}
}
m_Dispatcher为UI线程对应的Dispatcher,当线程t执行AddData方法时,Invoke方法会把其参数方法封送到UI线程中去执行。