Hi, @fatih uyanık. Welcome to Microsoft Q&A.
Task<List<Person>>
cannot be directly data bound, a converter is required to convert Task<List<Person>>
to List<Person>
. The reference code is as follows:
PersonListConverter.cs
[ValueConversion(typeof(Task<List<Person>>), typeof(List<Person>))]
public class PersonListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null) new List<Person>();
Task<List<Person>> temp = value as Task<List<Person>>;
List<Person> result = temp.Result;
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
MainWindow.xaml
<Window.Resources>
<local:PersonListConverter x:Key="MyPersonListConverter"></local:PersonListConverter>
</Window.Resources>
<DataGrid ItemsSource="{Binding PersonsTask,Converter={StaticResource MyPersonListConverter}}" >
However, temp.Result
is used in the above example, which will affect asynchrony (the Important part of the document has relevant descriptions)
You could refer to the following method to load data asynchronously:
Use ObservableCollection<Person>
to bind data. When you need to load data, get the data asynchronously and insert it into ObservableCollection<Person>
.
Reference examples: MainWindow.xaml
<Grid>
<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False" Loaded="MyDataGrid_Loaded">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Id}"></DataGridTextColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
MainWindowViewModel viewModel = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = viewModel;
MyDataGrid.ItemsSource = viewModel.PersonsTask;
}
private async void MyDataGrid_Loaded(object sender, RoutedEventArgs e)
{
await viewModel.GetDataAsync();
}
}
MainWindowViewModel.cs
public class MainWindowViewModel
{
public ObservableCollection<Person> PersonsTask = new ObservableCollection<Person>();
public async Task<ObservableCollection<Person>> GetPersons()
{
await Task.Delay(5000);
var persons = new ObservableCollection<Person>() {
new Person(){ Id = 1, Name = "AA"},
new Person(){ Id = 2, Name = "BB"}
};
return persons;
}
public async Task GetDataAsync()
{
var persons = await GetPersons();
//using System.Windows;
Application.Current.Dispatcher.Invoke(() =>
{
PersonsTask.Clear();
foreach (var person in persons)
{
PersonsTask.Add(person);
}
});
}
}
Person.cs
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
Note: In the above code, ObservableCollection
replaces List
because ObservableCollection
implements INotifyCollectionChanged
. More about INotifyCollectionChanged
: https://learn.microsoft.com/en-us/dotnet/api/system.collections.specialized.inotifycollectionchanged?view=net-9.0
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.