Juan Pablo Gomez
Juan Pablo Gomez

Reputation: 5524

Observablecollection.RemoveAt(item) doesn't refresh UI

I have an ObservableCollection<MyType>, where MyType implements INotifyPropertyChanged using Fody.

This collection was binded to my ui as this

<Grid x:Name="DetallePresupuesto" Grid.Row="2">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Text="{x:Static resources:Labels.SALUD_DetallePresupuesto}" Background="Bisque" TextAlignment="Center"/>
    <DataGrid 
        x:Name="DetallePresupuestoGrid" 
        Grid.Row="1" 
        Grid.ColumnSpan="1" 
        AutoGenerateColumns="False" 
        Style="{DynamicResource ParadigmaNDataGrid}" 
        ItemsSource="{Binding Path=DetallePresupuesto,UpdateSourceTrigger=PropertyChanged}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <cmd:EventToCommand Command="{Binding ItemSelectionChangedCommand}" CommandParameter="{Binding ElementName=DetallePresupuestoGrid, Path=SelectedItem}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="AddingNewItem">
                <cmd:EventToCommand Command="{Binding InsertItemCommand}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="{x:Static resources:Labels.GENERAL_Item}" Width="10*" ClipboardContentBinding="{x:Null}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Merlin_ConceptosFacturacion.StrDescripcionConcepto}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <controls:Search SearchParms="{Binding ElementName=EstaVentana,Path=DataContext.BusqItems}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="{x:Static resources:Labels.GENERAL_Cantidad}" Width="2*" Binding="{Binding Path=NumCantidad}" ClipboardContentBinding="{x:Null}"/>
            <DataGridTextColumn Header="{x:Static resources:Labels.GENERAL_ValorUnitario}" Width="2.5*" Binding="{Binding Path=NumValorFacturacionDigitado}" ClipboardContentBinding="{x:Null}"/>
            <DataGridTextColumn Header="{x:Static resources:Labels.GENERAL_ValorTotal}" Width="2.5*" Binding="{Binding Path=NumValor}" ClipboardContentBinding="{x:Null}"/>
            <DataGridTemplateColumn Width="70" Header="{x:Static resources:Labels.GENERAL_BorrarItem}" HeaderStyle="{StaticResource ResourceKey=ParadigmaNDataGridHeaderStyle}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Style="{StaticResource InLineDeleteButton}" Command="{Binding Path=DataContext.DeleteCommand, ElementName=EstaVentana}" CommandParameter="{Binding ElementName=DetallePresupuestoGrid,Path=SelectedItem}" Visibility="{Binding Merlin_ConceptosFacturacion.NumIdConcepto,Converter={cnv:decimalToVisibilityConverter}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>


private ObservableCollection<MyType> _DetallePresupuesto;
public ObservableCollection<MyType> DetallePresupuesto
{
    get {
        if (_DocumentoPresupuesto == null)
            return new ObservableCollection<MyType>();
        else
            return new ObservableCollection<MyType>(_DocumentoPresupuesto.Parent.MyType);
    }
    set { SetProperty(ref _DetallePresupuesto, value); }
 }

And this command that deletes one row each time

public void ExecuteDelete(object p)
{
    try
    {
        bool borro = false;
        MyType det = (MyType)p;
        MyType item = DetallePresupuesto.Where(x => x.NumIdTransaccion == det.NumIdTransaccion).FirstOrDefault();
        if (item != null)
        {
            DetallePresupuesto.RemoveAt(DetallePresupuesto.IndexOf(item));
            db.SetEntityState(det, EntityState.Deleted);
            db.SaveEntity(det);
        }
    }
    catch (Exception e)
    {
        ReportarInconsistencia(e.Message);
    }
}

My problem is when delete an item from the collection id does it but it doesn't refresh the UI.

How can I Do to force de UI refresh ?

Upvotes: 0

Views: 853

Answers (1)

default
default

Reputation: 11635

You're not binding to DetallePresupuesto in the UI. You are binding to either:

return new ObservableCollection<MyType>();

or

return new ObservableCollection<MyType>(_DocumentoPresupuesto.Parent.MyType);

For the UI to be updated you need to let the property return the list that you are removing from, i.e. the DetallePresupuesto. That means the getter should look something like this.

public ObservableCollection<MyType> DetallePresupuesto
{
    get {
        if (_DetallePresupuesto == null)
            _DetallePresupuesto = new ObservableCollection<MyType>(); //populate here

        return _DetallePresupuesto;
    }
}

Also, try to avoid setters for your collections.

Upvotes: 3

Related Questions