Using Entity Framork I have a many-to-many relationship. In WPF I have a form for creating items. The problem is that when I add sub-items the list is not updated automatically.
For the purposes of a sample I have the following that uses an in-memory SQLite database. The database has tables for posts and tags. The window just shows:
- a ListBox of available tags
- a ListBox of selected tags
- a second ListBox of selected tags for demonstration purposes
And a button for adding a tag. When an available tag is selected and the Add button is pushed, the tag is added to the third ListBox but not the second ListBox. Note that in the button click handler, I set the ItemsSource for the third ListBox to null then reset it. Since that works, I know that the tags are being added to the Tags collection but the second ListBox is just not being updated. How do I get it to be updated automatically?
The following is the DbContext and entities.
Code Snippet
internal class db : DbContext
{
public db(DbContextOptions options) : base(options) { }
public virtual DbSet Posts { get; set; }
public virtual DbSet Tags { get; set; }
}
public class Post
{
public event PropertyChangedEventHandler? PropertyChanged;
public long Id { get; set; }
public string? Name { get; set; }
public List? Tags { get; set; } = new List();
}
public class Tag : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public long Id { get; set; }
private string? title = string.Empty;
public List Posts { get; set; } = new List();
public Tag(string title)
{
this.title = title;
}
public string? Title
{
get { return title; }
set
{
if (value != title)
{
title = value;
NotifyPropertyChanged();
}
}
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The following is the XAML.
Code Snippet
The following is the code-behind.
Code Snippet
public partial class MainWindow : Window
{
db? db = null;
Post post = new Post();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var conn = new SqliteConnection("DataSource=:memory:");
conn.Open();
var options = new DbContextOptionsBuilder()
.UseSqlite(conn)
.Options;
//
db = new db(options);
try
{
db.Database.EnsureCreated();
}
catch (Exception ex)
{
MessageBox.Show($"Creation error: {ex.Message}");
return;
}
//
theGrid.DataContext = post;
db.Tags.Add(new Tag("Hobby"));
db.Tags.Add(new Tag("Profession"));
db.Tags.Add(new Tag("Housework"));
db.Tags.Add(new Tag("Animals"));
db.Tags.Add(new Tag("Shopping"));
db.Tags.Add(new Tag("Computers"));
//
AvailableTags.ItemsSource = db.Tags.Local.ToObservableCollection();
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
Tag? cat = AvailableTags.SelectedItem as Tag;
if (cat == null)
return;
if (cat.Title == null)
return;
post.Tags.Add(new Tag(cat.Title));
SelectedTagsTest.ItemsSource = null;
SelectedTagsTest.ItemsSource = post.Tags;
}
} 
Rajkiran SwainPosted Oct 16, 2023, 2:04 PM
You should use an ObservableCollection for your
post.Tagscollection, and this will automatically notify the UI to update when items are added or removed from the collection.Sam HobbsPosted Oct 16, 2023, 4:13 PM
Thank you! Yes, that works. Very simple modification. I should have figured that out but I did not.