2016-12-14 3 views
1

Je simple DataGridWPF DataGrid problème de sélection lors de l'obtention des données async

 <DataGrid x:Name="dgSample" ItemsSource="{Binding Items, IsAsync=True}" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="False" CanUserDeleteRows="False" SelectionUnit="FullRow"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/> 
       <DataGridTextColumn Header="Date" Binding="{Binding Date}" IsReadOnly="True"/> 
       <DataGridTemplateColumn Header="Sent" > 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <CheckBox IsChecked="{Binding Sent}" IsEnabled="False" HorizontalAlignment="Center"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 

Je renseigner ce DataGrid des articles objet

code derrière:

public List<Item> Items { get; set;} 

    private async void GetData() 
    { 
     await Task.Run(() => 
     { 
      GetItems(); 
     }); 
    } 

    private void GetItems() 
    { 
     Items = facade.GetItems(); 
    } 

Tout fonctionne bien, je récupère les données et remplit le datagrid async. Le problème vient quand je veux sélectionner une rangée, je ne peux pas. Je clique sur une cellule et la sélection disparaît automatiquement.

Quand je POPULATE synchronisation DataGrid le problème disparaît

+0

je ne voudrais pas utiliser un 'list', en général, vous voulez un' ObservableCollection' lié au ' ItemsSource'. À quelle fréquence remplissez-vous les 'Items'? Le faites-vous sur demande ou périodiquement? – mechanic

+0

Je remplis les éléments à la demande. Même si j'utilise ObservableCollection, le problème persiste. En outre, j'implémente INotifyPropertyChanged, donc il ne devrait y avoir aucun problème avec la liste user1416072

+0

Je suppose que vous pourriez avoir un autre code pour effacer la sélection, parce que ce code que vous montrez semble bon. Utilisez-vous un framework MVVM? Quand vous dites "Quand je remplis la synchronisation de datagrid" vous voulez dire que vous chargez les articles async ou vous supprimez IsAsync de la liaison dans xaml? –

Répondre

0

Vous devez utiliser async/await all the way down, sinon vous risquez de l'impasse le thread d'interface utilisateur.

Cela fonctionne pour moi (je Prism):

using Prism.Commands; 
using System; 
using System.Collections.Generic; 
using Prism.Mvvm; 
using System.Collections.ObjectModel; 
using Models; 
using System.Threading.Tasks; 

public class ItemsViewModel : BindableBase 
{ 
    private MyFacade facade; 
    public ItemsViewModel() 
    { 
     facade = new MyFacade(); 
     Items = new ObservableCollection<Item>(); 
    } 
    public ObservableCollection<Item> Items { get; private set; } 

    public DelegateCommand GetDataCommand => new DelegateCommand(GetData); 

    private async void GetData() 
    { 
     // it's the best practice to wrap an async void and use an async Task 
     await GetItems(); 
    } 

    private async Task GetItems() 
    { 
     // not really async 
     var result = await facade.GetItems(); 
     Items.Clear(); 
     Items.AddRange(result); 
    } 

    class MyFacade 
    { 
     public async Task<List<Item>> GetItems() 
     { 
      // not really async 
      var items = new List<Item>(); 
      items.Add(new Item { Name = "Joe", Date = DateTime.Now }); 
      items.Add(new Item { Name = "Bob", Date = DateTime.Now }); 
      items.Add(new Item { Name = "Sam", Date = DateTime.Now }); 
      return items; 
     } 
    } 
} 

Vue:

<UserControl x:Class="DataGridPopulatedAsync.Views.ItemsView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:prism="http://prismlibrary.com/" 
     prism:ViewModelLocator.AutoWireViewModel="True"> 
<StackPanel> 
    <Button Command="{Binding GetDataCommand}" Content="Get Data" /> 
    <DataGrid ItemsSource="{Binding Items}" /> 
</StackPanel> 
</UserControl>