UWP绑定到UserControl的Observable集合无法正常工作

时间:2016-08-12 21:33:46

标签: c# wpf data-binding uwp uwp-xaml

我有这个页面:NewsPage

<Page
x:Class="TouchTypeRacing.Views.NewsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TouchTypeRacing.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:TouchTypeRacing.Controls"
xmlns:models="using:TouchTypeRacing.Models"
DataContext="{Binding}"
mc:Ignorable="d">

<Grid Background="White">
    ....
    <ScrollViewer Grid.Row="1"
                  VerticalScrollBarVisibility="Auto"
                  Margin="5,10,5,0">
        <ItemsControl ItemsSource="{Binding Posts}"
                      x:Name="itemsControl">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate x:DataType="models:Post">
                    <controls:Post/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>
</Page>

页面的datacontext绑定到视图模型。 PageViewmModel
ItemsControl datatemplate是Post控件 页面上ItemsSource的{​​{1}}绑定到viewmodel的ItemsControl属性。

Posts

然后,视图模型:

public NewsPage()
{
    this.InitializeComponent();

    _viewModel = new NewsPageViewModel();
    DataContext = _viewModel;           
}

public class NewsPageViewModel { private ObservableCollection<Post> _posts = new ObservableCollection<Post>(); public ObservableCollection<Post> Posts { get { return _posts; } } public NewsPageViewModel() { GetPosts(_posts); } public static void GetPosts(ObservableCollection<Post> posts) { posts.Clear(); posts = new ObservableCollection<Post> { new Post { Id = "1", DateTime = DateTime.Today, User = Application.CurrentUser, Likes = 10, ImagePath = Application.CurrentUser.ImagePath, Message = "Test message", Comments = new ObservableCollection<Comment> { new Comment {Id= "1", Content="Comment1", User = Application.CurrentUser }, new Comment {Id= "2", Content="Comment2", User = Application.CurrentUser }, new Comment {Id= "3", Content="Comment3", User = Application.CurrentUser }, new Comment {Id= "4", Content="Comment4", User = Application.CurrentUser }, }, Last2Comments = new List<Comment> { new Comment {Id= "3", Content="Comment3", User = Application.CurrentUser }, new Comment {Id= "4", Content="Comment4", User = Application.CurrentUser }, } } }; } 显示为空。 我做错了什么?

2 个答案:

答案 0 :(得分:0)

我无法添加评论......所以:

在NewsPageViewModel的构造函数中,您初始化一个新的(但是空的)ObservableCollection。

如果您没有在GetPost-Method中添加元素,_posts将保持为空。

答案 1 :(得分:0)

如果要继续切换集合,NewsPageViewModel必须实现INotifyPropertyChanged并在更改集合实例时引发PropertyChanged。这是怎么回事。我还包括一个更简单的快速解决方案&#34;解决方案如下

public class VIewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] String propName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

public class NewsPageViewModel : ViewModelBase
{
    public NewsPageViewModel()
    {
        Posts = GetPosts();
    }

    private ObservableCollection<Post> _posts;
    public ObservableCollection<Post> Posts
    {
        get { return _posts; }
        set {
            _posts = value;
            OnPropertyChanged();
        }
    }

    protected ObservableCollection<Post> GetPosts()
    {
        //  do stuff to get posts, return new ObservableCollection<Post>
    }
}

快速修复

更容易从一个集合实例开始,所以UI获得了第一个(在这种情况下,只有)它抓取Posts的值的时间,保持相同的集合。但是,如果没有INotifyPropertyChanged,您就会遇到像这样的问题。试图在没有它的情况下使用WPF实际上是一种自我惩罚的练习。

ObservableCollection<Post> _posts = new ObservableCollection<Post>();

public ObservableCollection<Post> Posts { get { return _posts; } }
public NewsPageViewModel()
{
    GetPosts(_posts);
}
public static void GetPosts(ObservableCollection<Post> posts)
{
    posts.Clear();
    //  ...get posts
}

关于ObservableCollection的特殊之处在于它实现了INotifyCollectionChanged,它会在您从集合中添加或删除项目时通知UI - 但UI必须知道要侦听哪个集合变化。