Perhaps I don’t understand events fully.
I’m building a Windows Phone 7 app in Silverlight.
I have a UserControl that wraps a ListBox, called EditableListBox. The ListBox has a data template. The items in the list box are wrapped by EditableListItem objects.
The data template is as follows:
<DataTemplate>
<Grid ManipulationCompleted="Grid_ManipulationCompleted">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding Path=IconSource}"
Grid.Column="0"
Width="96"
Height="96"
VerticalAlignment="Center"
Visibility="{Binding Path=Editing, Converter={StaticResource visibilityConverter}}"
/>
<TextBlock Text="{Binding Path=Name}" Grid.Column="1" />
</Grid>
</DataTemplate>
I’m binding the Visibility to a property of each EditableListItem, so I need to implement INotifyPropertyChanged so updates to the backing items are reflected in the UI. (Right? Or is there a simpler way to do it?)
EditableListItem:
public class EditableListItem : INotifyPropertyChanged
{
private EditableListBox _parentListBox;
public event PropertyChangedEventHandler PropertyChanged;
public bool Editing
{
get
{
return _parentListBox.Editing;
}
}
public EditableListItem(Section section, EditableListBox parentListBox)
{
_parentListBox = parentListBox;
// after this line, _parentListBox.PropertyChanged is still null.
// why is that?
_parentListBox.PropertyChanged += PropertyChanged;
_parentListBox.PropertyChanged += new PropertyChangedEventHandler(_parentListBox_PropertyChanged);
}
EditableListBox:
public partial class EditableListBox : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// NotifyPropertyChanged will raise the PropertyChanged event,
// passing the source property that is being updated.
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void SetSectionsSource(ObservableCollection<Section> sectionsSource)
{
sectionsSource.CollectionChanged += new NotifyCollectionChangedEventHandler(sectionsSource_CollectionChanged);
ContentListBox.ItemsSource = sectionsSource.Select(section => new EditableListItem(section, this) { Enabled = true });
//ContentListBox.ItemsSource.Add(new EditableListItem(new Section("Section", 3)) { Enabled = true });
}
// ...
private bool _editing;
public bool Editing
{
get
{
return _editing;
}
set
{
_editing = value;
NotifyPropertyChanged("Editing");
}
}
}
The Editing property is stored in EditableListBox – EditableListItem just forwards it. I wanted to attached EditableListItem.PropertyChanged to EditableListBox.PropertyChanged directly, but the following didn’t work:
// after this line, _parentListBox.PropertyChanged is still null.
// why is that?
_parentListBox.PropertyChanged += PropertyChanged;
The following did work:
_parentListBox.PropertyChanged += new PropertyChangedEventHandler(_parentListBox_PropertyChanged);
Why is this? Is the first attempt totally invalid (if so, why does the compiler allow it?)?
To begin with, you don’t wire up the
PropertyChangedto implement it. The idea is that WPF uses that event and it wires it up. The only thing you do is trigger the event when applicable.And that’s a part of the issue here. You have the
Editingproperty, but it is not being fired. I do understand that you have wired thePropertyChangedof the parent listbox to get the event to fire, but that is not going to work.If I get the idea right, what you want to accomplish is when the
Editingproperty of the listbox gets changed, you want thePropertyChangedof the list item to be forced.One of the things of
PropertyChangedis that the sender has to be the object where thePropertyChangedis located. This means that you should implement it like this:I don’t know how you get the reference to the editable listbox, but lets say you get it via the constructor. When you get the reference, you attach the the
PropertyChangedevent handler of the listbox. Because, when theEditingproperty of that object changes, actually, yourEditingproperty changes too. This is how you simulate that.One last thing: the reason why the
PropertyChangedis stillnullafter the+= PropertyChangedis because thePropertyChangedof the object itself is null. You cannot wire the events in this way. The second way is the correct way of wiring up the events, and the above example shows what you do with this.