Reputation: 41
I have a (most probably) very simple question for you regarding a WPF Datagrid that I bound to a ObservableCollection and that unfortunately does not update when I add items to this Collection.
This is my View incl. the Datagrid:
<UserControl.Resources>
<local:SinglePackTransactions_ViewModel x:Key="vm"/>
</UserControl.Resources>
...
...
...
<DataGrid x:Name="DataGridRequestPacks_SinglePack" AutoGenerateColumns="False" Grid.Row="1" Width="700" Margin="30"
ItemsSource="{Binding SinglePackResultList, Source={StaticResource vm}}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Created" Width="Auto" Binding="{Binding Created}"/>
<DataGridTextColumn Header="Product Code" Width="Auto" Binding="{Binding ProductCode}"/>
</DataGrid.Columns>
</DataGrid>
When I click on a button (Command="SendRequestCmd") I add a an item of my custom class ("Pack") to my ObservableCollection SinglePackResultList. In the constructor of my ViewModel I have this here:
SinglePackResultList = new ObservableCollection<Pack>();
SendRequestCmd = new RelayCommand((object z) =>
{
try
{
SinglePackResultList.Add(SOAPRequest.SOAPRequestHandler(new Pack() {Created = (DateTime.Now).ToShortDateString(), ProductCode = ProductCode_SinglePack, BatchID = BatchID_SinglePack, BatchExpiry = BatchExpiry_SinglePack, PackSerialnumber = SerialNumber_SinglePack, PackTransaction = Transaction_SinglePack.TransactionID }));
}
catch (Exception)
{
return;
}
},
CanExecute);
When I set a debug point, I can see that after every button-click there is on additional item in my ObservableCollection SinglePackResultList - so this works.
But unfortunately the Datagrid stays empty. I tried to add a NotifyPropertyChanged("SinglePackResultList")
directly after the SinglePackResultList.Add(...)
, but this did not work as well.
I'm totally lost how I can get this working. :-(
Upvotes: 1
Views: 1793
Reputation: 41
based on your feedback, I could identify my mistake. I forgot to set the DataContext of my ViewModel and I removed the staticresource.
So here is what works for me - maybe this will also help others:
View-XAML:
<DataGrid x:Name="DataGridRequestPacks_SinglePack" AutoGenerateColumns="False" Grid.Row="1" Width="1150" Margin="30" ItemsSource="{Binding SinglePackResultList}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Created" Width="Auto" Binding="{Binding Created}"/>
<DataGridTextColumn Header="Product Code" Width="Auto" Binding="{Binding ProductCode}"/>
</DataGrid.Columns>
</DataGrid>
View.cs (Constructor):
public SinglePackTransactions_View()
{
InitializeComponent();
this.DataContext = new SinglePackTransactions_ViewModel();
}
In my ViewModel I just used the ObservableSollection as a property:
public ObservableCollection<Pack> SinglePackResultList { get; set; }
In the constructor of my ViewModel I used the bound ICommand-Button to add items to my ObservableCollection:
SinglePackResultList = new ObservableCollection<Pack>();
SendRequestCmd = new RelayCommand((object z) =>
{
try
{
SinglePackResultList.Add(
SOAPRequest.SOAPRequestHandler(
new Pack()
{
ProductCode = ProductCode_SinglePack,
BatchID = BatchID_SinglePack,
BatchExpiry = BatchExpiry_SinglePack,
PackSerialnumber = SerialNumber_SinglePack,
PackTransaction = Transaction_SinglePack.TransactionID
}
)
);
}
catch (Exception e)
{
return;
}
},
CanExecute);
Upvotes: 1
Reputation: 136
Two ways to deal with data binding in WPF.
Create in constructor and never change it. For example
public class A{
public ObservableCollection<int> ObserableList { get; set; }
public A() { ObservableList = new ObservableCollection<int>(); }
}
then you only add or remove elements in collection.
Or you can use full property and event PropertyChanged, in this way you can assign another collection to it.
public class A {
private ObservableCollection<int> observableList;
public ObservableCollection<int> ObservableList
{
get { return observableList; }
set
{
observableList = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ObservableList));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void Init()
{
ObservableList = new ObservableCollection<int>();
}
}
Upvotes: 2