The problem: A datagrid does not reflect at runtime when an item is added to the DataSource.
Note: When i click at another view and return to the view that contains the datagrid, it does reflect the added item. but this is not desirable as the view is actually regenerated which causes loss of the current state.
Datasource: The datasource is a table created in visual studio (local db) using Entity FrameworkCore.
The Code:
Datagrid showing bindings
<Grid Grid.Row="4">
<DataGrid
x:Name="DatagridPart"
Grid.Row="4"
AutoGenerateColumns="False"
ItemsSource="{Binding Parts, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding PartId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Header="Part No" />
<DataGridTextColumn
Binding="{Binding PartDescription, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Header="Description" />
<DataGridTextColumn
Binding="{Binding PartQuantity, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Header="Quantity" />
<DataGridTextColumn
Binding="{Binding PartTag, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Header="Tags" />
<DataGridTextColumn
Binding="{Binding UserID, UpdateSourceTrigger=PropertyChanged}"
Header="Added by" />
</DataGrid.Columns>
</DataGrid>
</Grid>
Binding properties and constructor of the relevant ViewModel classes (PartViewModel, BaseViewModel and PartCommand)
private ObservableCollection<Part> _parts;
public ObservableCollection<Part> Parts
{
get
{
return _parts;
}
set
{
_parts = value;
OnPropertyChanged(nameof(Parts));
}
}
//// Construction
public PartViewModel()
{
CreateCommand = new PartCommand(this);
_parts = PartDataAccess.GetPart();
}
public PartCommand CreateCommand { get; }
public void LoadPart()
{
_parts = new ObservableCollection<Part>(PartDataAccess.GetPart());
}
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
}
public class PartCommand : BaseCommand
{
private readonly PartViewModel _viewModel;
public PartCommand(PartViewModel viewModel)
{
_viewModel = viewModel;
}
public override void Execute(object? parameter)
{
PartDataAccess.AddPart(_viewModel.PartIdToDb,
_viewModel.PartDescription, _viewModel.PartQuantity,
_viewModel.PartTag, _viewModel.UserIdToDb);
_viewModel.LoadPart();
}
}
Method to retrieve data from the database.
public static ObservableCollection<Part> GetPart()
{
using (var db = new MikeInventoryContext())
{
return new ObservableCollection<Part>(db.Parts.ToList());
}
}
DataContext set in the code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
PartViewModel partViewModel = new PartViewModel();
this.DataContext = partViewModel;
}
}
Note: I have shown a very small portion of the code for clarity. If more information is needed, I will be delighted to provide them.
What I have Tried:
I have created a collection to serve as the database, and connected it to the datagrid using the same properties and bindings. It works fine.
public static ObservableCollection<Part2> _DatabaseParts = new ObservableCollection<Part2>
{
new Part2(){PartId=100, PartDescription = "Plier", PartQuantity = 12, PartTag = "Plier", SupplierId = 100, UserID = 101},
new Part2(){PartId=101, PartDescription = "Spanner", PartQuantity = 12, PartTag = "Spanner", SupplierId = 100, UserID = 102}
};
public static ObservableCollection<Part2> GetPart2()
{
return _DatabaseParts;
}
2
Answers
See solution here:
The problem arises from this line of code in the LoadPart() method:
_parts = new ObservableCollection(PartDataAccess.GetPart());
The private field "_parts" should be replaced with the public Property "Parts" or "this.Parts". The correct code will now be:
this.Parts = new ObservableCollection(PartDataAccess.GetPart());
Many thanks to you all for the assistance!
I think it may be just a typo in this portion of code. You specified the wrong type name to the OnPropertyChanged notify function.
Change
to
Edit: Clarity