简体   繁体   中英

WPF Datagrid does not update

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. :-(

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>();
    }
}

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM