2016-07-26 17 views
-1

Ich habe eine ListView, die ihre Itemsource zu Elements hat, die eine Liste von Schranken-Objects ist. Der SchrankePresenter ist der DataContext der Seite (im Konstruktor gesetzt).OnPropertyChanged aktualisiert die Ansicht nicht

Die Seite wird korrekt angezeigt, bis auf eine Schaltfläche geklickt wird. Wenn auf eine Schaltfläche geklickt wird, sollte sich der Wert Name der Schaltfläche ändern und die ListView sollte einen Eintrag mehr haben, aber nichts passiert/aktualisiert. Hier

ist der SchrankenPresenter:

public class SchrankePresenter : INotifyPropertyChanged 
    { 
     private List<Schranke> _elements; 
     public List<Schranke> Elements 
     { 
      get { return _elements; } 
      set 
      { 
       _elements = value; 
       OnPropertyChanged("Elements"); 
      } 
     } 
     public ICommand ClickCommand { get; set; } 
    private void OnPropertyChanged(string propName) 
    { 
     Debug.WriteLine($"on Property changed with {propName}"); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public SchrankePresenter() 
    { 
     var elements = new List<Schranke>(); 
     for (var i = 1; i < 15; i++) 
      elements.Add(new Schranke() { Name = $"{i}: Schranke" }); 

     Elements = elements; 
     Debug.WriteLine("ctor"); 
     ClickCommand = new DelegateCommand<Schranke>(ClickAction); 
    } 

    public void ClickAction(Schranke item) 
    { 
     VibrationDevice.GetDefault().Vibrate(TimeSpan.FromMilliseconds(150)); 

     Debug.WriteLine($"{item?.Name} was clicked"); 
     item.Name = "was clicked"; 
     OnPropertyChanged("Name"); 
     Elements.Add(new Schranke() { Name = "addednew element" }); 
     OnPropertyChanged("Elements"); 

    } 

} 

Die Klasse Schranke hat nur ein Mitglied: public string Name { get; set; }

Die Ansicht wie folgt aussieht:

<ListView ItemsSource="{Binding Elements, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="lv_schranken" Grid.Row="1" SelectedItem="{Binding SelectedItem}"> 

      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Button Height="80" 
          HorizontalAlignment="Stretch" 
          Command="{Binding ElementName=lv_schranken, Path=DataContext.ClickCommand}" 
          CommandParameter="{Binding}" 
          Style="{StaticResource TransparentStyle}"> 
         <Grid> 
           . 
           . (some grid stuff) 
           . 

          <TextBlock Name="schranken_name" 
             Grid.Row="1" 
             Grid.Column="1" 
             HorizontalAlignment="Center" 
             VerticalAlignment="Center" 
             FontWeight="ExtraLight" 
             FontSize="25" 
             Foreground="Black" 
             Text="{Binding Name, Mode=TwoWay}" /> 
         </Grid> 
        </Button> 
       </DataTemplate> 

      </ListView.ItemTemplate> 

     </ListView> 

PS: wenn einige Bedürfnisse der DelegateCommand - Umsetzung :

public class DelegateCommand<T> : ICommand 
    { 
    private Action<T> _clickAction; 

    public DelegateCommand(Action<T> clickAction) 
    { 
     _clickAction = clickAction; 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public void Execute(object parameter) 
    { 
     _clickAction((T)parameter); 
    } 
} 
+1

'OnPropertyChanged ("Name");' sollte in 'Schranke' Klasse aufgerufen werden, in' Name Setzer. – ASh

+0

Wenn Sie überhaupt geforscht hätten, wüssten Sie, dass man nicht an "List " bindet. –

+0

Ist es nicht möglich, die Liste zu verbindlichen Zwecken zu verwenden? – student96

Antwort

1

Wenn Ihr Mangel an eine Liste der Elemente zu binden, sollten Sie auf eine ObservableCollection binden:

Stellt eine dynamische Datenerfassung, die Benachrichtigungen bereitstellt, wenn Elemente hinzukommen, entfernt oder wenn die gesamte Liste wird aktualisiert .

https://msdn.microsoft.com/de-de/library/ms668604(v=vs.110).aspx

0

Für die Benutzeroberfläche von Viewmodel Aktualisierung sind wir zu erhöhten inotifypropertychanged erforderlich; observablecollection stellt die inotifypropertychanged-Implementierung standardmäßig bereit; wir können observablecollection für MVVm pattern verweisen.

Wenn Sie für die gleiche Liste verwenden, dann Sie müssen die inotifypropertychanged auf dieser speziellen Liste implementieren