I'm a beginner , just trying to understand MVVM , but I'm stuck on the many-to-many relationship. There is a rental table and a car table between which there are several to several connections. When I create a new rental , I select the cars I want to add from a listbox . But I don't know how to select those cars from the listbox and add them to the rental. Sorry if my phrasing is a bit complicated , but my English is not the best.
This is what the listbox looks like in AddEditRental.xaml :
<ListBox x:Name="CarsListBox"
Grid.Row="5"
ItemsSource="{Binding Cars}"
SelectedItem="{Binding SelectedCars, Mode=TwoWay}"
SelectionMode="Multiple"/>
This is what the RentalEditVM.cs looks like :
using RentalCar.Model;
using RentalCar.View;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
namespace RentalCar.ViewModel
{
internal class RentalEditVM : Entity
{
public ObservableCollection<Car> Cars { get; set; }
private Rental? rental;
public ListBox ListBox { get; set; }
public RentalEditVM()
{
Cars = new ObservableCollection<Car>();
Rental = new Rental();
}
public RentalEditVM(ObservableCollection<Car> cars, Rental rental = null)
{
Cars = cars;
Rental = rental ?? new Rental();
}
public Rental? Rental
{
get { return rental; }
set { SetProperty(ref rental, value); }
}
}
}
And finally this is what MainVM.cs looks like :
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.EntityFrameworkCore.Query;
using RentalCar.Logic;
using RentalCar.Model;
using RentalCar.View;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace RentalCar.ViewModel
{
internal class MainVM : ObservableRecipient
{
private MainLogic logic;
public ObservableCollection<Car> Cars { get; set; }
public ObservableCollection<Rental> Rentals { get; set; }
public ObservableCollection<Owner> Owners { get; set; }
public ICommand CreateOwner { get; }
public ICommand CreateRental { get; }
public ICommand CreateCar { get; }
public ICommand Delete { get; }
public ICommand Edit { get; }
public MainVM()
{
logic = new MainLogic();
Cars = new ObservableCollection<Car>();
Rentals = new ObservableCollection<Rental>();
Owners = new ObservableCollection<Owner>();
Cars.CollectionChanged += ObservableCollectionChanged;
Rentals.CollectionChanged += ObservableCollectionChanged;
Owners.CollectionChanged += ObservableCollectionChanged;
logic.Load(Rentals, Cars, Owners);
CreateOwner = new RelayCommand(() =>
{
var w = new AddEditOwner();
if (w.ShowDialog() == true)
{
var owner = (Owner)w.DataContext;
if (logic.Save(owner))
{
Owners.Add(owner);
}
}
});
CreateRental = new RelayCommand(() =>
{
var w = new AddEditRental();
w.DataContext = new RentalEditVM(Cars);
if (w.ShowDialog() == true)
{
var rental = ((RentalEditVM)w.DataContext).Rental;
if (logic.Save(rental))
{
Rentals.Add(rental);
}
}
});
CreateCar = new RelayCommand(() =>
{
var w = new AddEditCar();
w.DataContext = new CarEditVM(Owners);
if (w.ShowDialog() == true)
{
var car = ((CarEditVM)w.DataContext).Car;
if (logic.Save(car))
{
Cars.Add(car);
}
}
});
Delete = new RelayCommand<Entity>(entity =>
{
if(entity != null && ConfirmAction())
{
logic.Delete(entity);
}
});
Edit = new RelayCommand<Entity>(entity =>
{
if (entity == null) return;
Window w;
if(entity is Car)
{
w = new AddEditCar();
var vm = w.DataContext as CarEditVM;
w.DataContext = new CarEditVM(Owners , SelectedCar!);
}
else if(entity is Rental)
{
w = new AddEditRental();
var vm = w.DataContext as RentalEditVM;
w.DataContext = new RentalEditVM(Cars, SelectedRental!);
}
else
{
w = new AddEditOwner();
}
if(w.ShowDialog() == true)
{
if(!logic.Save(entity))
{
logic.RevertChanges(entity);
}
}
});
}
private void ObservableCollectionChanged(object? sender , NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach (ObservableObject x in e.NewItems)
{
x.PropertyChanged += Entity_PropertyChanged;
}
}
if(e.OldItems != null)
{
foreach (ObservableObject x in e.OldItems)
{
x.PropertyChanged -= Entity_PropertyChanged;
}
}
}
private void Entity_PropertyChanged(object? sender , System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == "DeletedAt")
{
if(sender is Car)
{
Cars.Remove(sender as Car);
}
else if(sender is Rental)
{
Rentals.Remove(sender as Rental);
}
else
{
Owners.Remove(sender as Owner);
}
}
}
private bool ConfirmAction()
{
return MessageBoxResult.Yes == MessageBox.Show("Are you sure about this?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
}
private Car? selectedCar;
private Rental? selectedRental;
private Owner? selectedOwner;
public Car? SelectedCar
{
get { return selectedCar; }
set { SetProperty(ref selectedCar, value); }
}
public Rental? SelectedRental
{
get { return selectedRental; }
set { SetProperty(ref selectedRental, value); }
}
public Owner? SelectedOwner
{
get { return selectedOwner; }
set { SetProperty(ref selectedOwner, value); }
}
}
}
I hope someone can help with this , because I have been suffering with it for a while
I've tried several ways to solve it , but no way , watched videos , talked to ChatGPT , but no way to solve it.