Automatically Update Database When Object Is Changed in a WinUI/WPF App

34 views Asked by At

I have an ObservableCollection called Clients which contains a list of Clients that is then displayed in a ListView. Currently whenever a new client is added, the List View automatically updates which is great. However it doesn't also add the client to the database which is what I would like to happen.

Currently I call "ClientData.AddClientData(client);" in the createClientBtn_Click function to add it to the database but I would like it to happen automatically in a binded kind of way in the same fashion that it updates the UI.

How can I trigger a database change whenever the ObservableCollection is changed?

Models

public class Order
{
    public int Id { get; set; }
    public float Amount { get; set; }
    public DateTime Date { get; set; }
    public Client Client {get; set;}
}

public class Client
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

View Models:

public class ViewModelBase : ObservableObject {}

public partial class ClientViewModel : ViewModelBase
{
     public ObservableCollection<Client> Clients { get; set; }        
     public ClientViewModel() {}
}

public partial class OrderViewModel: ViewModelBase
{
    public ObservableCollection<Order> Orders { get; set; }
    public OrderViewModel()  {}
}

View: MainWindow.xaml

<StackPanel x:Name="selectClientsPanel" HorizontalAlignment="Center">
    <ListView x:Name="clientsList" BorderThickness="1" Width="350" Height="Auto" HorizontalAlignment="Left"
   ItemsSource="{Binding Path=Clients, Mode=TwoWay}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType= "model:Client">
                <TextBlock Text="{x:Bind FirstName}" x:Phase="1" Margin="0,5,0,5"/>
                <TextBlock Text="{x:Bind LastName}" x:Phase="1" Margin="0,5,0,5"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView> 
    <StackPanel Margin="30">
                <TextBox x:Name="firstNameBox" Header="Enter first name:" PlaceholderText="First Name" />
                <TextBox Name="lastNameBoxBox" Width="250" Margin="0,0,8,0"
  Header="Enter last name:" PlaceholderText="Last Name"/>
                
                <Button x:Name="createClientBtn" Click="createClientBtn_Click">Create Client</Button>
            </StackPanel>   
</StackPanel>

MainWindow.xaml.cs:


public sealed partial class MainWindow : Window
{
    public ClientViewModel ViewModel { get; }
    public MainWindow()
    {
        this.InitializeComponent();
        ViewModel = App.GetService<ClientViewModel>();
        clientsList.ItemsSource = ViewModel.Clients;
    }

     private void createClientBtn_Click(Object sender, RoutedEventArgs e)
     {         
        if (firstNameBox.Text.Length > 0 && lastNameBox.Text.Length)
        {
           Client client=new User(firstNameBox.Text, lastNameBox.Text);
           ViewModel.Clients.Add(client);
           ClientData.AddClientData(client); //I want to call this automatically somehow
        }
     }
}

Database Related Code:

public class DataContext : DbContext
{
     public DbSet<Client> Clients { get; set; }
     public DbSet<Order> Orders { get; set; }
}

public static class ClientData
{
     public static void AddClientData(Client client)
     {
         using (var db = new CaseNoteManagerContext())
         {
             db.Add(client);
             db.SaveChanges();
         }
     }

    public static List<Client> GetClients()
    {
        using (var db = new DataContext())
        {        
            return db.Clients.ToList();
        }
    }
}

public static class OrderData
{
     public static void AddOrderData(Order order)
     {
         using (var db = new DataContext())
         {
             db.Add(order);
             db.SaveChanges();
         }
     }
}
1

There are 1 answers

2
Andrew KeepCoding On BEST ANSWER

You can use the ObservableCollection's CollectionChanged event:

Clients.CollectionChanged += Clients_CollectionChanged;
private void Clients_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action is NotifyCollectionChangedAction.Add)
    {
        // Add client to the database.
        return;
    }

    if (e.Action is NotifyCollectionChangedAction.Remove)
    {
        // Remove client from the database.
        return;
    }

    // etc...
}