Search code examples
c#listviewwindows-store-apps

Updating Listview after adding/removing item


How can I refresh ListView after adding item to collection in Windows Store app? Adding items to list works fine, but Listview doesn't refresh. I was trying to implement INotifyCollectionChanged, but what exactly should I do to make it work?

edit: XAML file

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView HorizontalAlignment="Left" Height="437" Margin="10,120,0,0" VerticalAlignment="Top" Width="593" ItemsSource="{Binding Persons, Mode=TwoWay}" Background="#FF5D5D5D">
        <ListView.DataContext>
            <Model:School/>
        </ListView.DataContext>
    </ListView>
    <Button Content="Button" HorizontalAlignment="Left" Margin="7,64,0,0" VerticalAlignment="Top" Command="{Binding AddCommand, Mode=OneWay}">
        <Button.DataContext>
            <Model:School/>
        </Button.DataContext>            
    </Button>
</Grid>

C# code:

class School
{
    private ObservableCollection<string> _persons = new ObservableCollection<string>()
    {
        "Name1", "Name2", "Name3"
    };

    public ObservableCollection<string> Persons
    {
        get { return _persons; }
    }

    private ICommand _addCommand;
    public ICommand AddCommand
    {
        get
        {
            return this._addCommand ??
                   (this._addCommand = new RelayCommand(Add));
        }
    }

    private void Add()
    {
        this._persons.Add("Name");
    }
}

Solution

  • You don't need to add INotifyCollectionChanged when you are using ObservableCollection - it already implements needed interfaces.

    Your code should work, though there may be some other problems:

    • check if the DataContext of your ListView (its parent in this case) is properly set - it should be set, so that 'ListView would find' Persons property,

    • also check if the ItemTemplate is properly set - example:

      <ListView Name="myList" ItemsSource="{Binding Persons}">
         <ListView.ItemTemplate>
             <DataTemplate>
                <StackPanel Orientation="Horizontal">
                   <TextBlock Text="{Binding Name}"/>
                   <TextBlock Text="{Binding Surname}"/>
                </StackPanel>
             </DataTemplate>
         </ListView.ItemTemplate>
      </ListView>
      
    • in your case there is no need that your ListView's ItemsSource uses TwoWay binding - you are not defining a setter ofr the property Persons.

    EDIT:

    After your edit, I can see where is the problem - you are setting separate DataContext for your ListView and Button - the button is adding to its own collection - different than ListView is bound to. Take a short test - set the DataContext of both to same staticresource:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <Model:School x:Key="mySchool"/>
        </Grid.Resources>
        <ListView HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="10,120,0,0" ItemsSource="{Binding Persons}" Background="#FF5D5D5D"
                  DataContext="{StaticResource mySchool}"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="7,64,0,0" VerticalAlignment="Top" Command="{Binding AddCommand, Mode=OneWay}"
                DataContext="{StaticResource mySchool}">
        </Button>
    </Grid>