2010-11-20 5 views
0

Je rencontre des difficultés avec les événements. Je construis une application Windows Phone 7.Silverlight: Problème avec INotifyPropertyChanged

J'ai quelques classes qui implémentent une zone de liste modifiable, qui peut passer en mode d'édition et permettre à l'utilisateur d'ajouter ou de supprimer des éléments. Le code derrière est le wrapper autour du ListBox.

EditableListBoxController<T> est la classe qui contrôle le comportement. Je l'ai rendu générique pour plus de sécurité de type, bien que cela signifie que j'ai besoin de le diviser en une classe distincte au lieu d'implémenter la fonctionnalité dans EditableListBox.xaml.cs, ce qui est un peu pénible.

EditableListItem est un seul article de la liste. Il enveloppe les éléments qui sont ajoutés ou supprimés, et est responsable de savoir si cet article fait partie de la liste, si l'icône « modifier » doit être affiché, etc.

EditableListBox.xaml:

<Grid x:Name="LayoutRoot"> 
    <ListBox x:Name="ContentListBox"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Grid ManipulationCompleted="Grid_ManipulationCompleted"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*" /> 
        </Grid.ColumnDefinitions> 

        <Image Source="{Binding IconSource}" 
          Grid.Column="0" 
          Width="96" 
          Height="96" 
          VerticalAlignment="Center" 
          Visibility="{Binding Editing, Converter={StaticResource visibilityConverter}}" 
          /> 

        <TextBlock Text="{Binding Name}" 
           Grid.Column="1" 
           Foreground="{Binding Enabled, Converter={StaticResource enabledConverter}}" /> 

       </Grid> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

Dans le modèle de données, l'icône d'édition se fixe à EditableListItem.Editing:

public bool Editing 
    { 
     get 
     { 
      return _parentListController.Editing; 
     } 
    } 

EditableListItem.Editing se lie à EditableListBoxController<T>.Editing:

EditableListItem implémente INotifyPropertyChanged, de sorte qu'il peut mettre à jour l'interface utilisateur de manière appropriée. Il écoute PropertyChanged sur le contrôleur de parent, il peut mettre à jour Editing quand il doit:

private EditableListBoxController<T> _parentListController; 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 


    public EditableListItem(T item, EditableListBoxController<T> parentListController) 
    { 
     _parentListController = parentListController; 
     _parentListController.PropertyChanged += PropertyChanged; 
     _parentListController.PropertyChanged += new PropertyChangedEventHandler(_parentListBox_PropertyChanged); 
     this.ContainedItem = item; 
    } 

    void _parentListBox_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(sender, e); 
     } 
    } 

Le constructeur de EditableListItem est appelé ici:

private void refreshItemsSource() 
    { 
     if (_sectionsSource == null) 
     { 
      return; 
     } 

     _editableListBox.ContentListBox.ItemsSource = (from section in _sectionsSource 
                 where Editing || section.Enabled 
                 select new EditableListItem<T>(section, this)).ToList(); 
    } 

Cependant, pour une raison quelconque, ce doesn ne fonctionne pas. Lorsque je modifie la propriété Editing du contrôleur, le gestionnaire d'événements PropertyChanged est null. Ainsi, l'événement ne se fait pas virer. C'est bizarre, parce que j'avance dans le débogueur et que je vois que le EditableListItem<T> enregistre son gestionnaire d'événements, mais il semble qu'il ait été désenregistré plus tard?

Qu'est-ce que je fais mal ici?

+0

Une suggestion, dans votre ensemble {} sur une propriété notifiante, vous devez vérifier si la nouvelle valeur == l'ancienne valeur avant d'affecter et d'élever une notification de modification.Si les valeurs sont == ils ne changent pas vraiment, non? –

+0

Bon, ils ne le sont pas, mais pour mon application cela ne fait pas vraiment de différence pour l'expérience utilisateur (pour autant que je sache.) –

Répondre

1

Le problème est probablement que vous liez à EditableListItem.Editing et aucun événement est soulevée pour indiquer que cela change, mais seulement que la propriété sous-jacente de la EditableListBoxController est en train de changer, mais ce n'est pas surveillé par le ListBox

En haut de ma tête je dirais que vous devriez avoir EditableListItem mettre en œuvre INotifyPropertyChanged. Ensuite, le EditableListItem doit se connecter à l'événement PropertyChange du EditableListBoxController.

Lorsque le contrôleur déclenche l'événement, le EditableListItem gère l'événement et tire sa propre propriété PropertyChanged' event indicating that the Editing` a changé.

+0

C'est exactement ce que j'essaie de faire, mais ça ne marche pas pour quelque raison. (voir le code ci-dessus.) –

Questions connexes