Damian Karwacki
Damian Karwacki

Reputation: 13

Observable Collection do not update the UI

I am working on the ability to add and delete rows in an observable collection. I have UserControl view with the ListView bound to the ObservableCollection. I have also delete command with is working in the ViewModel but don't update the UI.

This is my code on the ViewModel with is inherit from MvvmLight ViewModelBase class.

 public class ProductInfoViewModel : ViewModelBase
{
    #region Properties

    private ObservableCollection<Product> _productList;
    public ObservableCollection<Product> ProductList
    {
        get { return _productList; }
        set
        {
            _productList =  value;
            RaisePropertyChanged("ProductList");
        }
    }

    #endregion
    #region Constructor
    public ProductInfoViewModel()
    {
        ConnectWebService connect = new ConnectWebService();
        string json = connect.getResponse(@"http://localhost:8082/products");
        ProductList = JsonConvert.DeserializeObject<ObservableCollection<Product>>(json);
        DeleteCommand = new RelayCommand<long>((id) => DeleteCommandHandler(id, ProductList));
    }
    #endregion
    #region Commands
    public ICommand DeleteCommand { get; private set; }
    #endregion
    #region CommandsHandlers
    private void DeleteCommandHandler(long id, ObservableCollection<Product> productList)
    {
        try
        {
            productList.Remove(productList.Where(i => i.ProductId == id).First());

        }
        catch (Exception)
        {
        }
    }

This is my code in XAML:

<UserControl.DataContext>
    <local:ProductInfoViewModel/>
</UserControl.DataContext>
<Grid>
    <Grid Margin="0,50,0,100">
        <ListView  Margin="5" SelectionChanged="ListView_SelectionChanged" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Background="White" BorderBrush="{x:Null}" 
                   x:Name="ProductList">
            <ListView.View>
                <GridView>
                    <GridViewColumn  Header="Kod" Width="50" DisplayMemberBinding="{Binding ProductCode}"/>
                    <GridViewColumn  Header="Nazwa" Width="150" DisplayMemberBinding="{Binding ProductName}" />
                    <GridViewColumn  Header="Typ" Width="150" DisplayMemberBinding="{Binding ProductType}" />
                    <GridViewColumn  Header="Opis" Width="300" DisplayMemberBinding="{Binding ProductDescription}" />
                    <GridViewColumn  Header="Dostępność" Width="150" DisplayMemberBinding="{Binding ProductAvability}" />
                    <GridViewColumn Width="80">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Edytuj" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
                                        Click="Button_Click"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="80">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center" 
                                        Click="Delete_Click" Command="{Binding ProductInfoView.DeleteCommand, Mode=OneWay, Source={StaticResource Locator}}" CommandParameter="{Binding ProductId}"
                                         />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

My product class implements INotifyPropertyChanged interface, but I also use Fody.

Right now the view is updating only when I changing a view to another and then go back. I can't figure out what is wrong. I would be grateful for any help!

Upvotes: 1

Views: 1208

Answers (2)

mm8
mm8

Reputation: 169400

You are binding the Command property of the Button to the view model returned by your Locator resource. You should bind it to the same instance that the ListView is bound to:

<DataTemplate>
    <Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center" 
            Click="Delete_Click"
            Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=ListView}}" 
            CommandParameter="{Binding ProductId}"/>
</DataTemplate>

Upvotes: 0

stuicidle
stuicidle

Reputation: 317

When you delete items from the list you do not use your product list setter so RaisePropertyChanged does not get called. a quick fix would be to add a call to RaisePropertyChanged after you remove an item:

productList.Remove(productList.Where(i => i.ProductId == id).First());
RaisePropertyChanged("ProductList");

Upvotes: -1

Related Questions