在ObservableCollection中添加或删除项目时,列表框不会更新

时间:2013-08-14 12:24:08

标签: wpf windows-phone-7 listbox itemssource

我有一个“Hello World”类型的应用程序 listbox.ItemsSource =玩家。玩家是实施INotifyPropertyChanged的玩家的ObservableCollection。

当我在Players构造函数中添加项目时,项目显示正常。 当我更新现有项目时,会反映更改。 但是,当我为ObserveableCollection添加或删除项目时,列表框不会反映添加/删除的项目。

主页中的

xaml:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <ListBox Name="lstPlayers" ItemsSource="{Binding}" Margin="12,66,13,24" Grid.Row="1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!--<StackPanel Background="#FFD1D1D1">-->
                    <Grid Margin="0,0,0,0" Grid.RowSpan="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="60"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding Number}" FontSize="48"  />
                        <TextBlock Grid.Column="1" Text="{Binding Name}" FontSize="48" />
                    </Grid>
                    <!--</StackPanel>-->
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Button" Height="95" HorizontalAlignment="Left" Margin="183,350,0,0" Name="button1" VerticalAlignment="Top" Width="260" Click="button1_Click" />
        <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="198,472,0,0" Name="button3" VerticalAlignment="Top" Width="232" Click="button3_Click" />
    </Grid>

列表框绑定在后面的代码中:

  lstPlayers.ItemsSource = plys;

玩家等级:

using System.ComponentModel;
namespace DatabindList
{
public class TcrPlayer : INotifyPropertyChanged
{


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

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {

            if (_name != value)
                _name = value;

            NotifyPropertyChanged("Name");

        }
    }
   }
}

球员班:

using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace DatabindList
{

public class TcrPlayers : List<TcrPlayer> 
{
    public ObservableCollection<TcrPlayers> Items { get; private set; }



    public TcrPlayers()
    {
        //these are displayed
        Add(new TcrPlayer { Name = "Christine"});
        Add(new TcrPlayer { Name = "Janet"});
        Add(new TcrPlayer { Name = "Ian"});
    }


    public void AddPlayer()
    {
        //THIS HAS NO EFFECT ON THE LISTBOX
        Add(new TcrPlayer { Name = "Newbie", Number = "99" });

    }


   }
}

我可以使用

中的主页后面的代码更新列表中的现有项目
            var itm = lstPlayers.SelectedItem as TcrPlayer;
            itm.Name = "Fred";

但我无法反映对Players集合中的项目数量所做的任何更改。

2 个答案:

答案 0 :(得分:4)

TcrPlayers派生自List<TcrPlayer>并将项目添加到自身。但是,ObservableCollection<TcrPlayer>属性未以任何方式连接到该列表。假设plysTcrPlayers,你根本不绑定ObservableCollection - 你绑定到一个不可观察的List

继承ObservableCollection<TcrPlayer>而不是List<TcrPlayer>并删除未使用的属性可能会让您更接近您想要的位置。

顺便说一句,您并不经常使用此模式,因为除非您添加新功能,否则从集合类继承通常不被认为非常有用。通常,您只有父视图模型的ObservableCollection<TcrPlayer>属性,并将列表框的ItemsSource绑定到该视图。

说到这一点,您还要将ItemsSource设置为两次 - 在您的XAML中设置为{Binding},即当前DataContext,以及代码隐藏。

答案 1 :(得分:2)

您不使用ObservableCollection。相反,您的TcrPlayers类本身就是一个列表(派生自List<T>)。

来自ObservableCollection并删除您的Items媒体资源或使用Items.Add(..)代替Add()

E.g。

public class TcrPlayers : ObservableCollection<TcrPlayer> 
{
..

public class TcrPlayers
{
    public ObservableCollection<TcrPlayers> Items { get; private set; }

    public TcrPlayers()
    {
        //these are displayed
        Items.Add(new TcrPlayer { Name = "Christine"});
        Items.Add(new TcrPlayer { Name = "Janet"});
        Items.Add(new TcrPlayer { Name = "Ian"});
    }