Silverlight:INotifyPropertyChanged出现问题

时间:2010-11-20 18:22:49

标签: c# .net silverlight events

我遇到了很多事情。我正在构建一个Windows Phone 7应用程序。

我有一些实现可编辑列表框的类,可以切换到编辑模式,让用户添加或删除项目。

EditableListBox.xaml后面的代码是ListBox周围的包装器。

EditableListBoxController<T>是控制行为的类。为了更好的类型安全,我把它变成了通用的,虽然这意味着我需要将它分解为一个单独的类,而不是在EditableListBox.xaml.cs中实现功能,这是一种痛苦。

EditableListItem是列表中的单个项目。它包装正在添加或删除的项目,并负责知道该项目是否属于列表,是否应显示“编辑”图标等。

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>

在数据模板中,编辑图标绑定到EditableListItem.Editing

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

EditableListItem.Editing绑定到EditableListBoxController<T>.Editing

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

EditableListItem实现INotifyPropertyChanged,因此它可以适当地更新UI。它会监听父控制器上的PropertyChanged,因此它可以在需要时更新Editing

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

此处调用EditableListItem的构造函数:

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

但出于某种原因,这不起作用。当我更改控制器的Editing属性时,PropertyChanged事件处理程序为空。因此,事件不会被解雇。这很奇怪,因为我在调试器中单步执行并看到EditableListItem<T>正在注册其事件处理程序,但是它似乎在某种程度上已经被注销了?

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

问题可能是您绑定到EditableListItem.Editing并且没有引发任何事件来指示这种情况正在发生变化,只是EditableListBoxController的基础属性正在发生变化,但这并未受到ListBox

我想说你应该EditableListItem实施INotifyPropertyChanged。然后EditableListItem应该将自己连接到EditableListBoxController的PropertyChange事件。

当控制器触发事件​​时,EditableListItem将处理该事件并触发它自己的PropertyChanged' event indicating that the编辑`属性已更改。