'Updating ListView from database: 'No installed components were detected. Child collection must not be modified during measure or arrange.'
I am currently working on a simple task management MVVM application.
Minimal code of the project:
MainPage.xaml
<Page x:Class="TestArea.MainPage"
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="using:TestArea"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ListView x:Name="TasksListView"
Grid.Row="0"
ItemsSource="{x:Bind ViewModel.Tasks, Mode=OneWay}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Loaded">
<core:EventTriggerBehavior.Actions>
<core:InvokeCommandAction
Command="{x:Bind ViewModel.OnLoadedCommand, Mode=OneWay}" />
</core:EventTriggerBehavior.Actions>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Task">
<Border HorizontalAlignment="Stretch"
BorderBrush="Gray"
BorderThickness="1"
Background="White"
MinHeight="55">
<CheckBox VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
Content="{Binding Description, Mode=OneWay}"
IsChecked="{Binding IsCompleted, Mode=OneWay}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Checked">
<core:EventTriggerBehavior.Actions>
<core:InvokeCommandAction
Command="{Binding ElementName=TasksListView, Path=DataContext.OnCheckedTaskCommand}"
CommandParameter="{x:Bind Mode=OneWay}" />
</core:EventTriggerBehavior.Actions>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</CheckBox>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
MainPage.xaml.cs
namespace TestArea;
public sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
ViewModel = new MainPageViewModel();
}
public MainPageViewModel ViewModel
{
get => (MainPageViewModel) DataContext;
private set => DataContext = value;
}
}
MainPageViewModel.cs
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using Windows.UI.Xaml;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
namespace TestArea;
public class MainPageViewModel : ObservableObject
{
private DataContext _db;
public MainPageViewModel()
{
_db = new DataContext();
// Add items in db
for (int i = 1; i <= 10; i++)
{
var newTask = new Task
{
Id = i,
Description = $"Task-{i}",
IsCompleted = false
};
_db.Tasks.Add(newTask);
}
_db.SaveChanges();
Refresh();
OnLoadedCommand = new RelayCommand<RoutedEventArgs>(OnLoaded);
OnCheckedTaskCommand = new RelayCommand<Task>(OnCheckedTask);
}
private void Refresh()
{
Tasks = _db.Tasks.ToList();
}
private List<Task> _tasks;
public List<Task> Tasks
{
get => _tasks;
set => SetProperty(ref _tasks, value);
}
public ICommand OnLoadedCommand { get; }
private void OnLoaded(RoutedEventArgs e)
{
// Get data from db
Refresh();
}
public ICommand OnCheckedTaskCommand { get; }
private void OnCheckedTask(Task task)
{
// Find in db task with id == task.Id
var suitableTaskFromDb = _db.Tasks.First(taskInDb => taskInDb.Id == task.Id);
if (suitableTaskFromDb != null)
{
// Mark as completed
suitableTaskFromDb.IsCompleted = true;
// Save changes and refresh view
_db.SaveChanges();
Refresh();
}
}
}
TaskModel.cs
namespace TestArea;
public class Task
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsCompleted { get; set; }
}
DataContext.cs
using System;
using System.IO;
using Microsoft.EntityFrameworkCore;
namespace TestArea;
public sealed class DataContext : DbContext
{
public DataContext()
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
DbPath = Path.Combine(path, "TestApp.db");
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite($"Data Source={DbPath}");
}
public string DbPath { get; }
public DbSet<Task> Tasks { get; set; }
}
References:
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Tools
Microsoft.NETCore.UniversalWindowsPlatform
Microsoft.Toolkit.Mvvm
Microsoft.UI.Xaml.Markup
Microsoft.Xaml.Behaviors.Uwp.Managed
Universal Windows
To store data I am using SQLite database and Entity Framework library.
In the UI part I have a ListView which contains tasks that are presented as CheckBox controls. If the task is completed - you need to check the checkbox. Loading the records themselves from the database seems to be in okay, I can see the created records in ListView. However, the problem arises with the IsChecked property and saving/reading from the database IsCompleted parameter. At least I understand that, because the problem came after I added OnCheckedTaskCommand.
When I click on the checkbox, I get the following exception:
System.Exception: 'No installed components were detected.
Child collection must not be modified during measure or arrange.'
This exception was originally thrown at this call stack:
[External Code]
TestArea.MainPageViewModel.Tasks.set(System.Collections.Generic.List<TestArea.Task>) in MainPageViewModel.cs
TestArea.MainPageViewModel.Refresh() in MainPageViewModel.cs
TestArea.MainPageViewModel.OnCheckedTask(TestArea.Task) in MainPageViewModel.cs
[External Code]
What could be the cause?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
