开发者

Silverlight: Problem with INotifyPropertyChanged

I'm having difficulty with events. I'm building a Windows Phone 7 app.

I have a few classes that implement an editable list box, that can switch into editing mode and let the user add or remove items.

EditableListBox.xaml and the code behind is the wrapper around the ListBox.

EditableListBoxController<T> is the class that controls the behavior. I made it generic for greater type safety, although that means that I need to break it into a separate class instead of implementing the functionality in EditableListBox.xaml.cs, which is kind of a pain.

EditableListItem is a single item in the list. It wraps the items that are being added or removed, and is responsible for knowing if that item belongs in the list, if the "edit" icon should be displayed, 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>

In the data template, the editing icon binds to EditableListItem.Editing:

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

EditableListItem.Editing binds to EditableListBoxController<T>.Editing:

    private bool _editing;
    public bool Editing
    {
        get
        {
            return _editing;
        }
        set
        {
            _editing = value;
            NotifyPropertyChanged("Editing");
            refreshItemsSource();
        }
    }

EditableListItem implements INotifyPropertyChanged, so it can update the UI appropriately. It liste开发者_运维技巧ns to PropertyChanged on the parent controller, so it can update Editing when it needs to:

    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);
        }
    }

The EditableListItem's constructor is called here:

    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();
    }

For some reason, however, this doesn't work. When I change the controller's Editing property, the PropertyChanged event handler is null. Thus, the event doesn't get fired. This is odd, because I step through in the debugger and see that the EditableListItem<T> is registering its event handler, yet somehow it appears to have been deregistered later?

What am I doing wrong here?


The problem is probably that you are binding to EditableListItem.Editing and no event is being raised to indicate this is changing, only that the underlying property of the EditableListBoxController is changing, but this is not being monitored by the ListBox

Off the top of my head I would say that you should have EditableListItem implement INotifyPropertyChanged. Then the EditableListItem should wire it self to the PropertyChange event of the EditableListBoxController.

When the controller fires the event the EditableListItem will handle the event and fire it's own PropertyChanged' event indicating that theEditing` property has changed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜