私が達成しようとしていることを複製する例がここにあります。次のコードが示すように、ビューにバインドされたObservableCollectionプロパティを更新するViewModelがあります。通常、モデルから取得した結果からコレクションを更新しますが、この例で十分であることを願っています。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Controls;
namespace MVVMWpf.ViewModel
{
public class ListViewModel
{
public ObservableCollection<int> SomeObjectCollection { get; set; }
public ListViewModel()
{
SomeObjectCollection = new ObservableCollection<int>();
}
public void Do()
{
for (int i = 1; i < 1000000; i++)
{
int i1 = i;
SomeObjectCollection.Add(i1);
}
}
}
}
残念ながら、これはこのUIをブロックします。ループが完了するまで実行された場合にのみ、ビューが更新されます。私がそれを解決した方法は、MVVMの概念を破ります。だから私はあなたの助けが必要です。私はこのようにしました。
public class ListViewModel
{
private delegate void LongRunningProcess();
public ObservableCollection<int> SomeObjectCollection { get; set; }
private ListBox listBox;
public ListViewModel(ListBox listBox)
{
this.listBox = listBox;
SomeObjectCollection = new ObservableCollection<int>();
}
public void Do()
{
Thread thread = new Thread(() =>
{
for (int i = 1; i < int.MaxValue; i++)
{
int i1 = i;
listBox.Dispatcher.Invoke(
new LongRunningProcess(() =>
SomeObjectCollection.Add(i1);
}});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
ご覧のとおり、ViewModelはUIからlistBox要素を認識しています。また、MVVMダイアグラムを見ると、ビューのみがバインディングを介してViewModelへの参照を持っている必要があります。この問題をどのように克服しますか?ありがとう。