使用MVVM绑定ObservableCollection

时间:2014-01-24 05:24:20

标签: c# mvvm windows-phone-8 observablecollection

我正在尝试将应该是一个非常基本的MVVM示例放在一起,但是我无法让它工作。基本上,我想将ObservableCollection绑定到ListBox,并为用户提供搜索选项以搜索其他项目。在搜索时,应该刷新ListBox,因为集合将会更改。这是我的代码:

型号:

public class Item
   public string Name { get; set; }
}

视图模型:

public class ViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Item> _items { get; set; }
    public ObservableCollection<Item> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            RaisePropertyChanged("Items");
        }
    }

    public void GetDefaultItems()
    {
        ObservableCollection<Item> temp = new ObservableCollection<Item>();
        temp.Add(new Item() { Name = "abc" + " 1" });
        temp.Add(new Item() { Name = "def" + " 2" });
        temp.Add(new Item() { Name = "ghi" + " 3" });
        Items = temp;
    }


    public void Search(string query)
    {
       ObservableCollection<Item> temp = new ObservableCollection<Item>();
       temp.Add(new Item() { Name = query + " 1" });
       temp.Add(new Item() { Name = query + " 2" });
       temp.Add(new Item() { Name = query + " 3" });
       Items = temp;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

查看:

<Grid x:Name="LayoutRoot">
    <ListBox ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock x:Name="Name" Text="{Binding Name}" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

MainPage.xaml中:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel>
        <TextBox x:Name="txtSearch"/>
        <TextBlock Text="Items:" />
        <views:ItemView x:Name="ItemsOnPage" />
    </StackPanel>
</Grid>

最后,MainPage.xaml.cs:

public partial class MainPage : PhoneApplicationPage
{
    private ViewModel vm;

    // Constructor
    public MainPage()
    {
        InitializeComponent();
        txtSearch.KeyUp += txtSearch_KeyUp;
        vm = new ViewModel();
    }

    void txtSearch_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            vm.Search(txtSearch.Text);
        }
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        vm.GetDefaultItems();
        ItemsOnPage.DataContext = vm.Items;
    }
}

所以会发生什么,我可以看到第一次加载默认项目,但是当我搜索时,列表不会刷新。它现在都是硬编码所以如果搜索确实有效我会看到3个项目,无论他们搜索什么。

我注意到的是,如果我在RaisePropertyChanged的ViewModel中设置断点,this.PropertyChanged 始终为null ,那么它永远不会在if声明。我已经看到在模型上使用INotifyPropertyChanged的示例,但在这种情况下,因为我需要在集合更改时收到通知,所以在视图模型上使用似乎是正确的。这可能是错的,但我不确定如何设置它。

谁能看到我做错了什么?

2 个答案:

答案 0 :(得分:4)

尝试这样做

  1. 将ItemSource设置为Items

  2. 清除并添加数据项

    String preQuery="";
    public void Search(string query)
    {
       if(preQuery==query)
          return;
    
       Items.Clear();
    
       Items.Add(new Item() { Name = query + " 1" });
       Items.Add(new Item() { Name = query + " 2" });
       Items.Add(new Item() { Name = query + " 3" }); 
    }
    
  3. 希望这会有所帮助。

答案 1 :(得分:0)

看起来项目集合的值没有在UI上刷新。

试试这个 -

MainPage.cs

中的代码
   private ViewModel _viewModel;

MainPage 构造函数

  _viewModel = new ViewModel();
  this.DataContext = _viewModel ;

在MainPage中绑定 XAML

<views:ItemView x:Name="ItemsOnPage" DataContext="{Binding Path=Items,UpdateSourceTrigger=PropertyChanged}"/>