2015-01-27 4 views
2

Рассмотрим следующий пример кода:ListView не обновляется на ItemSource ObservableCollection Пункт изменения свойств

View.xml

<Grid> 
    <ListView Name="NameList" HorizontalAlignment="Left" Height="142" Margin="55,45,0,0" VerticalAlignment="Top" Width="389"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="Auto"/> 
        </Grid.ColumnDefinitions> 
        <Label Content="{Binding FirstName}"/> 
        <Label Content="{Binding LastName}" Grid.Column="1"/> 
       </Grid> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
    <Button Content="Button" HorizontalAlignment="Left" Margin="120,256,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 

</Grid> 

View.xml.cs

public partial class MainWindow : Window 
{ 
    ViewModel vm; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     vm = new ViewModel(); 
     this.DataContext = vm; 
     NameList.ItemsSource = vm.fn; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     vm.fn.Add(new fullname("P", "Q")); 
     vm.fn[0].FirstName = "NewName"; 
    } 

} 

ViewModel.cs

class ViewModel : INotifyPropertyChanged 
{ 

    public ViewModel() 
    { 
     fn = new ObservableCollection<fullname>(); 
     fn.CollectionChanged += ContentCollectionChanged; 
     fn.Add(new fullname("A", "B")); 
     fn.Add(new fullname("C", "D")); 
    } 

    public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == NotifyCollectionChangedAction.Remove) 
     { 
      foreach (fullname item in e.OldItems) 
      { 
       //Removed items 
       item.PropertyChanged -= EntityViewModelPropertyChanged; 
      } 
     } 
     else if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (fullname item in e.NewItems) 
      { 
       //Added items 
       item.PropertyChanged += EntityViewModelPropertyChanged; 
      } 
     } 
    } 

    public void EntityViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     //This will get called when the property of an object inside the collection changes 
    } 

    public ObservableCollection<fullname> _fn; 
    public ObservableCollection<fullname> fn 
    { 
     get { return _fn; } 
     set { _fn = value; OnPropertyChanged("fn"); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 

     } 
    } 
} 

Режим l.cs

class fullname : INotifyPropertyChanged 
{ 
    public fullname(string f, string l) 
    { 
     FirstName = f; 
     LastName = l; 
    } 

    public string _FirstName; 
    public string FirstName 
    { 
     get { return _FirstName; } 
     set { _FirstName = value; OnPropertyChanged("FirstName"); } 
    } 


    public string _LastName; 
    public string LastName 
    { 
     get { return _LastName; } 
     set { _LastName = value; OnPropertyChanged("LastName"); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 

     } 
    } 
} 

Если добавить или удалить какие-либо элементы в ObservableCollection он обновляет ListView в представлении правильно, но проблема в том, что если я изменить свойство ObservableCollection элемента элемент управления ListView не обновляется.

для: При щелчке вышеуказанной кнопки
a. Добавляет новый элемент (успешно отражено в ListView)
b. Изменить FirstName первого элемента (не отражено в ListView)

Что я должен делать, чтобы изменения отражались в представлении.

Я был бы очень благодарен, если бы кто-нибудь мог указать, что я делаю неправильно.

+1

Является ли это упрощенной версией кода или вы действительно не делаете событие 'INPC.PropertyChanged' в методе OnPropertyChanged? Вы получаете обработчик, но вы не возбуждаете событие: 'handler (this, new PropertyChangedEventArgs (name));' – dkozl

ответ

3

Событие ObservableCollection не запускается, когда элемент изменен, только когда он добавлен, удален или перемещен. Вы должны реализовать интерфейс INotifyPropertyChanged в классе item и зарегистрировать каждое событие элемента в коллекции.

См here

Если вы тяжелые изменения в коллекции, вы можете поднять

NotifyCollectionChangedAction.Reset

событие, чтобы сбросить их все

См here

+0

Я прочитал эту ссылку и реализовал то же самое, но не успел и снова перепроверялся. При обнаружении отладки он не вводит EntityViewModelPropertyChanged(). Должен ли я отправлять код? – Parshuram

+0

Убедитесь, что item.PropertyChanged + = EntityViewModelPropertyChanged; вызывается для каждого элемента. Вы можете опубликовать свой код. –

+0

Написал код. item.PropertyChanged + = EntityViewModelPropertyChanged вызывается для каждого элемента fullname в ObservableCollection. Но при внесении изменений элемент управления не переходит в EntityViewModelPropertyChanged. – Parshuram

Смежные вопросы