Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步获取数据时WPF Datagrid选择问题_C#_Wpf_Datagrid_Wpfdatagrid - Fatal编程技术网

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

C# 异步获取数据时WPF Datagrid选择问题,c#,wpf,datagrid,wpfdatagrid,C#,Wpf,Datagrid,Wpfdatagrid,我有一个简单的数据网格 <DataGrid x:Name="dgSample" ItemsSource="{Binding Items, IsAsync=True}" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="False" CanUserDeleteRows="False" SelectionUnit="FullRow"> <DataGrid.Co

我有一个简单的数据网格

        <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对象填充此datagrid

代码隐藏:

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

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

    private void GetItems()
    {
       Items = facade.GetItems();   
    }
公共列表项{get;set;}
私有异步void GetData()
{
等待任务。运行(()=>
{
GetItems();
});
}
私有void GetItems()
{
Items=facade.GetItems();
}
一切正常,我获取数据并异步填充datagrid。问题是当我想选择一行时,我不能。我点击一个单元格,选择就会自动消失

当我填充datagrid sync时,您需要使用的问题消失了,否则可能会死锁UI线程

这对我很有用(我用的是Prism):

使用Prism.Commands;
使用制度;
使用System.Collections.Generic;
使用Prism.Mvvm;
使用System.Collections.ObjectModel;
使用模型;
使用System.Threading.Tasks;
公共类ItemsViewModel:BindableBase
{
私人门面;
public ItemsViewModel()
{
facade=newmyfacade();
Items=新的ObservableCollection();
}
公共可观测集合项{get;private set;}
公共DelegateCommand GetDataCommand=>new DelegateCommand(GetData);
私有异步void GetData()
{
//包装异步void并使用异步任务是最佳实践
等待GetItems();
}
私有异步任务GetItems()
{
//不是真正异步的
var result=await facade.GetItems();
Items.Clear();
Items.AddRange(结果);
}
类MyFacade
{
公共异步任务GetItems()
{
//不是真正异步的
var items=新列表();
添加(新项{Name=“Joe”,Date=DateTime.Now});
添加(新项{Name=“Bob”,Date=DateTime.Now});
添加(新项{Name=“Sam”,Date=DateTime.Now});
退货项目;
}
}
}
视图:


您需要使用,否则可能会死锁UI线程

这对我很有用(我用的是Prism):

使用Prism.Commands;
使用制度;
使用System.Collections.Generic;
使用Prism.Mvvm;
使用System.Collections.ObjectModel;
使用模型;
使用System.Threading.Tasks;
公共类ItemsViewModel:BindableBase
{
私人门面;
public ItemsViewModel()
{
facade=newmyfacade();
Items=新的ObservableCollection();
}
公共可观测集合项{get;private set;}
公共DelegateCommand GetDataCommand=>new DelegateCommand(GetData);
私有异步void GetData()
{
//包装异步void并使用异步任务是最佳实践
等待GetItems();
}
私有异步任务GetItems()
{
//不是真正异步的
var result=await facade.GetItems();
Items.Clear();
Items.AddRange(结果);
}
类MyFacade
{
公共异步任务GetItems()
{
//不是真正异步的
var items=新列表();
添加(新项{Name=“Joe”,Date=DateTime.Now});
添加(新项{Name=“Bob”,Date=DateTime.Now});
添加(新项{Name=“Sam”,Date=DateTime.Now});
退货项目;
}
}
}
视图:



我不会使用
列表
,通常您希望将
可观察集合
绑定到
项目资源
。您多久填充一次
?您是按需还是定期?我按需填充项目。即使我使用ObservableCollection,问题仍然存在。另外,我实现了INotifyPropertyChanged,因此列表应该没有任何问题。我猜您可能会有另一个代码清除选择,因为您显示的代码看起来不错。您是否正在使用任何MVVM框架?当您说“当我填充datagrid sync时”,您的意思是加载异步项,还是从xaml中的绑定中删除IsAsync?出于测试目的,我创建了wpf窗口,所有绑定都是代码绑定(没有MVVM)。通过“填充datagrid sync”,我的意思是更改GetData()方法:private void GetData()不带async/wait,我不会使用
列表
,通常您希望将
可观察集合
绑定到
项资源
。您多久填充一次
?您是按需还是定期?我按需填充项目。即使我使用ObservableCollection,问题仍然存在。另外,我实现了INotifyPropertyChanged,因此列表应该没有任何问题。我猜您可能会有另一个代码清除选择,因为您显示的代码看起来不错。您是否正在使用任何MVVM框架?当您说“当我填充datagrid sync时”,您的意思是加载异步项,还是从xaml中的绑定中删除IsAsync?出于测试目的,我创建了wpf窗口,所有绑定都是代码绑定(没有MVVM)。通过“填充datagrid sync”,我的意思是更改GetData()方法:private void GetData(),而不使用async/await
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>