C# Listbox WPF привязка таблицы entinty framework
У меня есть Listbox, который при запуске я заполняю из базы данных ef, но при изменении коллекции у меня не обновляются данные в форме
Код DataContext:
public class DataContext : DbContext
{
public DbSet<ChatDb> ChatDb { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string path = "Data Base";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
optionsBuilder.UseSqlite(@$"Data Source={path}\\Data Base.db");
}
}
Код класса ChatDb:
public class ChatDb
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public string ID { get; set; } = null!;
public string Name { get; set; } = null!;
}
Так заполняю коллекцию
using (DataContext db = new DataContext())
{
db.Database.EnsureCreated();
ChatDb chatDb = new ChatDb() { Name = "ddd", ID = "ssss" };
db.ChatDb.Add(chatDb);
lock (this)
db.SaveChanges();
ListBoxChats.ItemsSource = db.ChatDb.ToList();
}
}
Код ListBox:
<ListBox Style="{DynamicResource ListBoxStyleRound}" HorizontalContentAlignment="Stretch" x:Name="ListBoxChats" Grid.Column="1" Grid.Row="3" Grid.RowSpan="7" MaxHeight="198" Background="#FFFFFF" BorderBrush="#A8A8A8" Margin="5,0,51,0" SelectionChanged="ListBoxChats_SelectionChanged" >
<ListBox.DataContext>
<Model:ChatDb ID="ID" Name="Name"/>
</ListBox.DataContext>
<ListBox.ItemTemplate >
<DataTemplate>
<Grid Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="Tbs" Grid.Column="0" Grid.Row="0" FontSize="14" Margin="3,0,0,0" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="3,0,0,5" />
<Rectangle Stroke="#EBEBEB" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" RadiusX="2" RadiusY="2" />
<Button x:Name="DeleteChat" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Padding="3" FontSize="15" BorderBrush="Transparent" Background="Transparent" Foreground="Red" Click="DeleteChat_Click" Content="X"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Я могу заполнять через ObservableCollection, реализую интерфейс INotifyPropertyChanged и все данные редактируются и т.п. А со связкой базы данных ef не получается, и не понял для класса ChatDb реализовать интерфейс INotifyPropertyChanged.
Ответы (1 шт):
Автор решения: Иван Рудаков
→ Ссылка
Решение которое работает у меня Класс DataContext
public class DataContext : DbContext
{
public DbSet<ChatDb> ChatDb { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string path = "Data Base";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
optionsBuilder.UseSqlite(@$"Data Source={path}\\Data Base.db");
}
}
Таблица с данными
public class ChatDb
{
public int Id { get; set; }
public string ChatId { get; set; } = null!;
public string Name { get; set; } = null!;
}
Listbox
<ListBox Style="{DynamicResource ListBoxStyleRound}" ItemsSource="{Binding ChatDb}" HorizontalContentAlignment="Stretch" x:Name="ListBoxChats" Grid.Column="1" Grid.Row="3" Grid.RowSpan="7" MaxHeight="198" Background="#FFFFFF" BorderBrush="#A8A8A8" Margin="5,0,51,0" SelectionChanged="ListBoxChats_SelectionChanged" >
<ListBox.ItemTemplate >
<DataTemplate>
<Grid Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="Tbs" Grid.Column="0" Grid.Row="0" FontSize="14" Margin="3,0,0,0" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding ChatId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="3,0,0,5" />
<Rectangle Stroke="#EBEBEB" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" RadiusX="2" RadiusY="2" />
<Button x:Name="DeleteChat" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Padding="3" FontSize="15" BorderBrush="Transparent" Background="Transparent" Foreground="Red" Click="DeleteChat_Click" Content="X"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
MainWindow
using Casis.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Casis
{
public partial class MainWindow : Window
{
DataContext db = new DataContext();
public MainWindow()
{
InitializeComponent();
Loaded += Window_Loaded;
GridSms.Visibility = Visibility.Hidden;
GridComands.Visibility = Visibility.Hidden;
GridPosting.Visibility = Visibility.Hidden;
GridGlavnaya.Visibility = Visibility.Visible;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
db.Database.EnsureCreated();
// загружаем данные из БД
db.ChatDb.Load();
// и устанавливаем данные в качестве контекста
ListBoxChats.ItemsSource = db.ChatDb.Local.ToObservableCollection();
}
//Добавление
private void BtnAddChat_Click(object sender, RoutedEventArgs e)
{
var chatModel = new ChatDb() { Name = TbChatName.Text, ChatId = TbChat.Text };
db.ChatDb.Add(chatModel);
db.SaveChanges();
ListBoxChats.Items.Refresh();
}
//Редактирование
private void TbName_TextChanged(object sender, TextChangedEventArgs e)
{
BtnAddChatBackground();
var chatName = ListBoxChats.SelectedItem as ChatDb;
if (chatName == null)
return;
var res = db.ChatDb.FirstOrDefault(x => x.Name == chatName.Name);
if (res != null)
{
res.Name = TbChatName.Text;
db.SaveChanges();
ListBoxChats.Items.Refresh();
}
}
//Удаление
private void DeleteChat_Click(object sender, RoutedEventArgs e)
{
if (ListBoxChats.SelectedItems != null)
{
var SelectedItem = ((ListBoxItem)ListBoxChats.ContainerFromElement((Button)sender)).Content;
if (SelectedItem == null)
return;
if (SelectedItem is ChatDb chatModel)
{
db.ChatDb.Remove(chatModel);
db.SaveChanges();
ListBoxChats.Items.Refresh();
}
}
}
}
}