Why does IEnumerable <T> require a ToList call to update the list?

I am sure there is a good explanation for this. I suppose this is due to the fact that I have a cold and something implicit ...

I have a simple window:

<Window x:Class="WpfIdeas.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:w="clr-namespace:WpfIdeas"
    Title="Window1" Height="300" Width="315">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" x:Name="btnAddObject" Click="btnAddObject_Click">Add Object</Button>
        <ListView Grid.Row="1"  ItemsSource="{Binding Objects}">
        </ListView>
    </Grid>
</Window>

code outside the window:

using System.Windows;

namespace WpfIdeas
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = new ObjectVM();
        }

        private void btnAddObject_Click(object sender, RoutedEventArgs e)
        {
            (DataContext as ObjectVM).AddObject();
        }
    }
}

And its DataContext is set by the following class:

class ObjectVM : INotifyPropertyChanged
{
    private readonly List<ObjectModel> objects = new List<ObjectModel>();

    //public IEnumerable<ObjectModel> Objects { get { return objects } } //doesn't work
    public IEnumerable<ObjectModel> Objects { get { return objects.ToList() } } //works

    private Random r = new Random();

    public void AddObject()
    {
        ObjectModel o = new ObjectModel(r);
        objects.Add(o);
        if(PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Objects"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

A class ObjectModelis actually a structure that generates a 14-character string when it is created. The method ToString()simply prints this line.

Since the code above, when I click the "Add Object" button, ListViewa new line appears in the line.

However, if I delete the call ToList()in the property Objects, ListViewnothing is displayed in. It just stays empty.

Why is this?

+3
4

:

, IEnumerable. , , INotifyCollectionChanged. , , .

+4

objects.ToList() . , ?

... NotifyPropertyChanged, , ( return objects - ).

+2

PropertyChanged , , , . Objects , , - , ToList() ToArray().

, PropertyChanged, , , , . .

ObservableCollection<T> - , INotifyCollectionChanged. , INotifyCollectionChanged, PropertyChanged (, ), CollectionChanged (, ).

, , ObservableCollection<T>. , . IEnumerable<T>, .

+2

, IEnumerable Linq, - , List < > Collection < > . , , (Linq) "", , , , yielding . Linq. Linq - , .

, , , ; , - , . , ListBox , ICollectionView. ICollectionView - , , IEnumerable. , . ObjectModel... , , , ToList().

0

Source: https://habr.com/ru/post/1765093/


All Articles