1

スレッド内のDataGridにアイテムを追加したい。Dispatcher:ディスパッチャ操作を中止する

は、私は私のユーザーコントロールのビューモデルを持っている:

public class Contact 
{ 
    public string Name { get; set; } 
    public string Phone { get; set; } 
} 

public class ContactGridViewModel 
{ 
    public ContactGridViewModel() 
    { 
     Items = new ObservableCollection<Contact>(); 
    } 

    public ObservableCollection<Contact> Items { get; private set; } 

    public Dispatcher Dispatcher 
    { 
     get { return Dispatcher.CurrentDispatcher); } 
    } 
    private DispatcherOperation LastOperation { get; set; } 

    public void Update(IEnumerable<Contact> contacts) 
    { 
     if (LastOperation != null) LastOperation.Abort(); 

     Items.Clear(); 
     foreach (var item in contacts) 
      LastOperation = Dispatcher.BeginInvoke(
        DispatcherPriority.Background, 
        new ParameterizedThreadStart(o => Items.Add(o))), 
        item); 
    } 
} 

マークアップの例があります:

Updateメソッドが二度目に実行された後
<!--DataContext="{Binding ContactGridViewModel}--> 

<DataGrid ItemsSource="{Binding Items, Mode=OneWay}"> 
    <DataGrid.Columns> 
    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" /> 
    <DataGridTextColumn Header="Phone" Binding="{Binding Path=Phone}" /> 
    </DataGrid.Columns> 
</DataGrid> 

、そして最初のコレクションは完全に追加されていない場合、 DataGridには、最初のコレクションの一部と完全な2番目のコレクションが含まれます。

私はDispatcherOperationを中止しようとしますが、Itemsプロパティに連絡先を追加することは停止しません。

DataGrid ItemsSourceにオブジェクトを追加する正しい方法を教えてください。あなたはcontactList1内のすべての項目のDispatcher.BeginInvoke()を開始していますが、Update(contactList2)を入力した場合にのみ、完全なforeachのが、単一Items.Add()ないLastOperation、いったん中止し、あなたのUpdate(contactList1)方法で

+0

Abort()は何を返しますか?最初のコレクションのどの部分が残っていますか? – LPL

+0

@LPLはtrueを返します。最初のコレクションの最後の部分は残ります。 – ebashmakov

答えて

2

は、この(テストしていない)のようなものを試してみてください。

public class ContactGridViewModel 
{ 
    public ContactGridViewModel() 
    { 
     Items = new ObservableCollection<Contact>(); 
     LastOperations = new List<DispatcherOperation>(); 
    } 

    public ObservableCollection<Contact> Items { get; private set; } 
    private ICollection<DispatcherOperation> LastOperations { get; set; } 

    public Dispatcher Dispatcher 
    { 
     get { return Dispatcher.CurrentDispatcher); } 
    } 

    private void StopUpdating() 
    { 
     foreach (var operation in LastOperations) 
     { 
      operation.Abort(); 
     } 
     LastOperations.Clear(); 
    } 

    public void Update(IEnumerable<Contact> contacts) 
    { 
     StopUpdating(); 

     Items.Clear(); 
     foreach (var item in contacts) 
      LastOperations.Add(Dispatcher.BeginInvoke(
        DispatcherPriority.Background, 
        new ParameterizedThreadStart(o => Items.Add(item))), 
        item)); 
    } 
} 
1

。あなたは、リスト内のすべてのDispatcherOpretationsを収集し、それらすべてを中止しなければならない

public void Update(IEnumerable<Contact> contacts) 
{ 
    if (LastOperation != null) LastOperation.Abort(); 

    Items.Clear(); 
    LastOperation = Dispatcher.BeginInvoke(
     DispatcherPriority.Background, 
     new ParameterizedThreadStart(o => { foreach (var item in o) Items.Add(item); }), 
     contacts); 
} 
+0

すべての商品が追加されるまでお待ちください – ebashmakov

+0

ありがとうございます、あなたは私を正しい解決に導いてくれました – ebashmakov

関連する問題