This is the first time I have to ask in this forum. I am developing my first WPF application that takes data from ASYNC methods to display whith a spinner while it is working.
I had no problems doing one (called CheckServices() that fills data in Labels, TextBlocks....), but I had an error doing a second method (called FillDataGrid(() that fills data in a DataGrid).
I come from web applications and I am not sure if I am doing it like in Ajax calls that I usually do.
My MainView:
public MainViewController()
{
InitializeComponent();
InitializeElements();
FillDataGrid(() =>
{
return new ItemService().ReadItemsByUser(SessionData.UserCertificate.User.DNI);
});
CheckServices();
Title = SessionData.AppData.AppName + " v" + SessionData.AppData.AppVersion;
Show();
}
This is the Method that works well:
async private void CheckServices()
{
//Show spinner
icoWorking.Visibility = Visibility.Visible;
List<ServiceModel> services =//From other method
Task<List<ServiceModel>> task = Task.Run(()=> {
foreach (ServiceModel ser in services)
{
//A proccess
}
return services;
});
services = await task;
// A process to asign data to view elements
//Hide spinner
icoWorking.Visibility = Visibility.Hidden;
}
This is the method that brokes the app:
async private void FillDataGrid(Func<List<ItemRepositoryDTO>> p)
{
List<RepositoryModel> list = null;
//Show spinner
icoWorking.Visibility = Visibility.Visible;
List<ItemRepositoryDTO> items = p();
if (items != null)
{
Task<List<RepositoryModel>> task = Task.Run(() =>
{
List<RepositoryModel> listAux = new List<RepositoryModel>();
//A proccess with "items"
return listAux;
});
list = await task;
//Problematic sentence ****
dgRepositoryItems.ItemsSource = list;
//*****
}
//Hide spinner
icoWorking.Visibility = Visibility.Hidden;
}
If I comment "the problematic sentence", it works well, else the error comes when the method ends (not when items are asigned to the DataGrid). If I dont use async methods it works well but the spinner do not show. Tried Task.WaitAll(t)/Task.WhenAll(t) + t.Result in MainWindow but that method always break the app without going througth "catch".
The XAML looks like this:
<DataGrid CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserSortColumns="False" ItemsSource="{Binding RepositoryModel}" x:Name="dgRepositoryItems" AutoGenerateColumns="False" BorderBrush="{x:Null}" Margin="0,60,0,41" Background="#FFECECEC">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#FF50B262"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Nombre" IsReadOnly="True" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,0,0,0"/>
</Style>
</StackPanel.Resources>
<fa:ImageAwesome Visibility="{Binding ShowRootPath}" VerticalAlignment="Bottom" Height="14" Icon="ArrowCircleOutlineRight" Foreground="Black" />
<TextBlock Text="{Binding GridTab}" />
<fa:ImageAwesome VerticalAlignment="Bottom" Height="14" Icon="{Binding IconPath}" Foreground="Gray" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn IsReadOnly="True" Width="*" Header="Repositorio" Binding="{Binding Repository}" />
<DataGridTemplateColumn Header="Estado" IsReadOnly="True" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,0,0,0"/>
</Style>
</StackPanel.Resources>
<fa:ImageAwesome VerticalAlignment="Bottom" Height="14" Icon="{Binding IconState}" Foreground="{Binding IconStateColor}" />
<TextBlock Text="{Binding State}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Can someone tell me what I am doing wrong and a simple example that how should it be to do the same?
Thanks in advance
UPDATE
The problem seems to be other different thing:
In the Task that prepares data to be inserted in the DataGrid, I was filling a field with class SolidColorBrush
.
It seems cannot be created in other thread than in the UI one.
Solved using Brush
instead SolidColorBrush
.
I found the solution here
Blockquote