This one gave me some headache, but as always, looking back the solution is pretty obvious.

Using WPF, in a MVVM design pattern, I have a ListView bound to a ObservableCollection. Straight forward senario.

XAML:

<ListView Name="lvCustomerSearchResults" ItemsSource="{Binding CustomerSearchResults}" SelectedItem="{Binding SelectedCustomer}" ...

 

ViewModel:

 

public async Task<AOTaskResult<List<CustomerSearchResultEntity>>> SearchCustomers(string cvrNo, Statuses? status = null, DateTime? fromDate = null, DateTime? toDate = null)
{
    return await Task.Run(() =>
    {
        AOTaskResult<List<CustomerSearchResultEntity>> result = new AOTaskResult<List<CustomerSearchResultEntity>>();
        try
        {
            result.Response = _repository.LstCustomers(cvrNo, status, fromDate, toDate, out List<NezCusCustomerDTO> dtos);
            if (result.Response.Success)
            {
                result.Result = dtos.Select(d => LocalMapping.ToCustomerSearchResultEntity(d)).ToList();
            }
        }
        catch (Exception ex) { CheckTaskException(ex); }
        return result;
    });
}

 

Trouble is when I click an item in the ListWiew I get a “Must create DependencySource on same Thread as the DependencyObject”-exception. It turns out that the reason I get this exception is that I created the items in the ObservableCollection on another thread than the main-thread. So, obviously, the solution is to create the the ObservableCollection items on the main-thread:

public async Task<AOTaskResult<List<CustomerSearchResultEntity>>> SearchCustomers(string cvrNo, Statuses? status = null, DateTime? fromDate = null, DateTime? toDate = null)
{
    AOTaskResult<List<CustomerSearchResultEntity>> result = new AOTaskResult<List<CustomerSearchResultEntity>>();
    List<NezCusCustomerDTO> dtos = null;

    await Task.Run(() =>
    {
        try
        {
            Busy = true;
            result.Response = _repository.LstCustomers(cvrNo, status, fromDate, toDate, out dtos);

            Busy = false;
        }
        catch (Exception ex) { CheckTaskException(ex); }
    });
    if (dtos != null && result.Response.Success)
    {
        result.Result = dtos.Select(d => LocalMapping.ToCustomerSearchResultEntity(d)).ToList();
    }
    return result;
}

 

 IMO, the code is not as clean ... but it works :-)

 

As always feel to ask or comment.


Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading