locked
Проблема с NotifyCollectionChangedEventHandler RRS feed

  • Вопрос

  • Возникла проблема, никак не хочет обновляться listbox. Если руками добавить в коллекцию, то все отображается, а вот через кнопочку не хочет. Не хочет срабатывать event на изменение коллекции, при то что новые items добросовестно добавляются в эту саму коллекцию. Подскажите пожалуйста, что я упустил?

     public class P_list : INotifyCollectionChanged
        {
            public event NotifyCollectionChangedEventHandler CollectionChanged;
            public ObservableCollection<Mega_P> all_p_list { get; set; }
          
            public void add_P(Mega_P mp)
            {
                all_pl_list.Add(mp);
                all_pl_list_CollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, mp));    
            }
    
            public void all_pl_list_CollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                if (CollectionChanged != null)
                {   
                    CollectionChanged(this, e);
                }
            }

    5 февраля 2013 г. 7:33

Ответы

  • Во первых ObservableCollection уже реализует интерфейс INotifyCollectionChanged из чего следует, что либо наследуйте свой класс от ObservableCollection либо внутренний список сделайте обычным List<T>, делайте класс перечислимой коллекцией и с инетрфейсом  INotifyCollectionChanged.

    А во вторых привязку к списку в вашем случае надо делать так:

    <Grid HorizontalAlignment="Left" Height="485" Grid.Row="1" VerticalAlignment="Top" Width="456" >
                <Grid.DataContext>
                    <local:P_list x:Key="list"/>
                </Grid.DataContext>
            
                <ListBox x:Name="Main_listbox" LostFocus="Main_listbox_LostFocus_1" ItemsSource="{Binding Source={StaticResource list}}" SelectionMode="Single">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" Tap="TextBlock_Tap_1" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </Grid>



    • Изменено Kirill Bessonov 5 февраля 2013 г. 13:09
    • Помечено в качестве ответа Abolmasov Dmitry 12 февраля 2013 г. 9:24
    5 февраля 2013 г. 13:05
  • Если вы в качестве ItemsSource устанавливаете коллекцию типа ObservableCollection<T> инфраструктура сама "подписывается" на событие изменения коллекции и обновляет элементы в интерфейсе если вы добавляете или удаляете элементы из вашей коллекции.

    Практическое руководство. Создание и привязка коллекции "ObservableCollection"

    • Помечено в качестве ответа Abolmasov Dmitry 12 февраля 2013 г. 9:24
    8 февраля 2013 г. 10:40

Все ответы

  • Добрый день.

    У вас проблема не в коллекции. Причем в вашем случае, похоже, даже INotifyCollectionChanged не требуется. Выложите Binding (XAML) и обработчик кнопки, по которому вы добавляете элемент.

    5 февраля 2013 г. 8:20
    Отвечающий
  • Вот так вот выглядит xaml

     <Grid HorizontalAlignment="Left" Height="485" Grid.Row="1" VerticalAlignment="Top" Width="456" >
                <Grid.DataContext>
                    <local:P_list/>
                </Grid.DataContext>
            
                <ListBox x:Name="Main_listbox" LostFocus="Main_listbox_LostFocus_1" ItemsSource="{Binding all_p_list}" SelectionMode="Single">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" Tap="TextBlock_Tap_1" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </Grid>

    и вот так обработчик

      

    void M_add_ public P_list vm = new P_list();

    Completed(object sender, PopUpEventArgs<string, PopUpResult> e) { if (e.Result.Length > 0) { var mp = new Mega_P() { ... }; vm.add_P(mp); } }



    • Изменено Alan Linvile 6 февраля 2013 г. 0:26
    5 февраля 2013 г. 8:36
  • Во первых ObservableCollection уже реализует интерфейс INotifyCollectionChanged из чего следует, что либо наследуйте свой класс от ObservableCollection либо внутренний список сделайте обычным List<T>, делайте класс перечислимой коллекцией и с инетрфейсом  INotifyCollectionChanged.

    А во вторых привязку к списку в вашем случае надо делать так:

    <Grid HorizontalAlignment="Left" Height="485" Grid.Row="1" VerticalAlignment="Top" Width="456" >
                <Grid.DataContext>
                    <local:P_list x:Key="list"/>
                </Grid.DataContext>
            
                <ListBox x:Name="Main_listbox" LostFocus="Main_listbox_LostFocus_1" ItemsSource="{Binding Source={StaticResource list}}" SelectionMode="Single">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" Tap="TextBlock_Tap_1" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </Grid>



    • Изменено Kirill Bessonov 5 февраля 2013 г. 13:09
    • Помечено в качестве ответа Abolmasov Dmitry 12 февраля 2013 г. 9:24
    5 февраля 2013 г. 13:05
  • Привет.

    Пожалуйста, не забудьте отметить сообщение, решающее вашу проблему как ответ. Для этого под каждым сообщением есть кнопка "Пометить как ответ".

    Спасибо


    Для связи [mail]

    6 февраля 2013 г. 11:14
  •  public class ViewModel 
        {
            public ObservableCollection<Mega_P> all_p_list { get; set; }
            
            public ViewModel()
            {
                all_pl_list = new ObservableCollection<Mega_P>();
            }
     
            public void add_P(Mega_P mp)
            {
                all_pl_list.Add(mp);
                all_pl_list.CollectionChanged += all_pl_list_CollectionChanged;
            }

            void all_p_list_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                ...
            }
        }

    и в XAML

    <Grid HorizontalAlignment="Left" Height="485" Grid.Row="1" VerticalAlignment="Top" Width="456" >
                <Grid.Resources>
                    <local:P_list x:Key="plist"/>
                </Grid.Resources>
            
                <ListBox x:Name="Main_listbox" LostFocus="Main_listbox_LostFocus_1" ItemsSource="{Binding Source={StaticResource plist}}" SelectionMode="Single">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" Tap="TextBlock_Tap_1" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </Grid>

    и такой вариант binding не работает, не отображаются данные.
    7 февраля 2013 г. 1:21
  • В таком варианте надо делать иначе:

    1. Grid.Resources убрать вообще

    2. ItemsSource="{Binding Path=all_p_list, SelectionMode="Single"}"

    Я то в начале думал, что коллекция у вас отдельным классом...

    7 февраля 2013 г. 3:51
  • Отлично! binding работает. Спасибо. Изменение коллекции отлавливается со второго раза и ListBox не обновляется. Мне кажется что в all_p_list_CollectionChanged надо что-то другое писать.

    public void all_p_list_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
             
            }


    8 февраля 2013 г. 3:04
  • А что вы хотите сделать в обработке события изменения коллекции?
    8 февраля 2013 г. 6:08
  • Я  хочу чтобы при добавление в коллекцию в listbox отображался добавленный объект.
    8 февраля 2013 г. 10:09
  • Если вы в качестве ItemsSource устанавливаете коллекцию типа ObservableCollection<T> инфраструктура сама "подписывается" на событие изменения коллекции и обновляет элементы в интерфейсе если вы добавляете или удаляете элементы из вашей коллекции.

    Практическое руководство. Создание и привязка коллекции "ObservableCollection"

    • Помечено в качестве ответа Abolmasov Dmitry 12 февраля 2013 г. 9:24
    8 февраля 2013 г. 10:40