I am using MVVM with WPF and still figuring things out.
The problem I am having is, I call an api that returns a List of data. I add the list of data to an observable collection. (This api gets called when the window opens.) When the window opens the GridView is empty. Only when I hardcode data into my constructor does it show.
I want the data from my API show when the page is opened.
What am I doing wrong and how can I solve this?
Any help and guidance will be appreciated.
My view xaml
<Window x:Class="ErrorLogger_WPF.Views.ExceptionDetailsListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ErrorLogger_WPF.Views" xmlns:viewmodels="clr-namespace:ErrorLogger_WPF.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:ExceptionDetailsListViewModel}"
mc:Ignorable="d"
Title="ExceptionDetailsListView" Height="450" Width="800">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView HorizontalAlignment="Left" VerticalAlignment="Top" Name="ExceptionList" ItemsSource="{Binding ExceptionDetails}" Height="Auto" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Exception ID" DisplayMemberBinding="{Binding Path=Id}" Width="Auto"/>
<GridViewColumn Header="Exception Type" DisplayMemberBinding="{Binding Path=ExceptionType}" Width="Auto"/>
<GridViewColumn Header="Exception Message" DisplayMemberBinding="{Binding Path=ExceptionMessage}" Width="Auto"/>
<GridViewColumn Header="Inner Exception" DisplayMemberBinding="{Binding Path=InnerException}" Width="Auto"/>
<GridViewColumn Header="Exception Source File" DisplayMemberBinding="{Binding Path=ExceptionSourceFile}" Width="Auto"/>
<GridViewColumn Header="Exception Source Line" DisplayMemberBinding="{Binding Path=ExceptionSourceLine}" Width="Auto"/>
<GridViewColumn Header="Exception Caller" DisplayMemberBinding="{Binding Path=ExceptionCaller}" Width="Auto"/>
<GridViewColumn Header="Date and Time Logged" DisplayMemberBinding="{Binding Path=dateLogged}" Width="Auto"/>
<GridViewColumn Header="View/Edit" Width="auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button x:Name="Open" Content="Open Or Edit"
Command="{Binding Path=DataContext.OpenExceptionCommand,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}"
CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Content="Button" HorizontalAlignment="Left" Margin="237,138,0,0" Grid.Row="1" VerticalAlignment="Top" Command="{Binding RefreshDataGridCommand}"/>
</Grid>
</Grid>
my xaml.cs file
using ErrorLogger_WPF.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ErrorLogger_WPF.Views
{
/// <summary>
/// Interaction logic for ExceptionDetailsListView.xaml
/// </summary>
public partial class ExceptionDetailsListView : Window
{
public ExceptionDetailsListView()
{
DataContext = new ExceptionDetailsListViewModel();
InitializeComponent();
}
}
}
My viewmodel
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ErrorLogger_WPF.Services;
using ErrorLogger_WPF.Views;
using Shared;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ErrorLogger_WPF.ViewModels
{
internal partial class ExceptionDetailsListViewModel : ObservableObject
{
#region Properties
public ObservableCollection<ExceptionDetails> ExceptionDetails { get; set; }
#endregion
APIService apiService = new APIService();
public ExceptionDetailsListViewModel()
{
LoadData();
}
private async void LoadData()
{
var exceptionDetails = await apiService.GetExceptionDetails();
ExceptionDetails = new ObservableCollection<ExceptionDetails>(exceptionDetails);
}
[RelayCommand]
private void OpenException(ExceptionDetails exDetails)
{
var detailedExceptionView = new DetailedExceptionView(exDetails);
detailedExceptionView.ShowDialog();
}
[RelayCommand]
private void RefreshDataGrid()
{
LoadData();
}
}
}