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?
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? –
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.) –