获取数据异步时WPF Datagrid选择问题

时间:2016-12-14 20:36:02

标签: c# wpf datagrid wpfdatagrid

我有一个简单的数据网格

        <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>

我从Items对象

填充此数据网格

代码背后:

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

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

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

一切正常,我获取数据并填充datagrid异步。当我想选择一行时,问题出现了,我不能。我点击一个单元格,选择会自动消失。

当我填充datagrid同步时,问题就会消失

1 个答案:

答案 0 :(得分:0)

您需要使用async/await all the way down,否则可能会使UI线程死锁。

这适合我(我使用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;
        }
    }
}

查看:

<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>