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); 
    } 
} 

마크 업 예제가있다 :

업데이트 방법은 두 번 실행 된 후
<!--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에는 첫 번째 컬렉션의 일부와 두 번째 전체 컬렉션이 포함됩니다.

// contactList1 and contactList2 are IEnumerable<Contact> objects 
Model.Update(contactList1); 
Model.Update(contactList2); 

나는 DispatcherOperation을 중단하려고 시도하지만 항목 속성에 연락처를 추가하는 것을 중지하지는 않습니다.

DataGrid ItemsSource에 개체를 추가하는 올바른 방법을 알려주시겠습니까? 당신의 Update(contactList1) 방법에서

+0

Abort()는 무엇을 반환합니까? 첫 번째 컬렉션의 어떤 부분이 첫 번째 또는 마지막으로 남았습니까? – LPL

+0

@LPL true를 반환합니다. 첫 번째 컬렉션의 마지막 부분은 그대로 유지됩니다. – ebashmakov

답변

2

당신은 목록에있는 모든 DispatcherOpretations를 수집하고 그들 모두를 중단해야한다.

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

당신은 contactList1의 모든 항목에 대한 Dispatcher.BeginInvoke()을 시작하지만 Update(contactList2)을 입력하면 당신은 단지 전체 foreach는하지만, 하나의 Items.Add()하지 않은 LastOperation, 일단 중단. (하지 테스트)이 같은

시도 뭔가 :

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