UWP 绑定到 UserControl 的 Observable 集合不起作用
UWP Binding to Observable Collection of UserControl not working
我有这个页面: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>
页面的数据上下文绑定到视图模型。 PageViewmModel
ItemsControl
数据模板是一个 Post
控件。
页面上ItemsControl
的ItemsSource
绑定到viewmodel的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 },
}
}
};
}
ItemsControl
显示为空。
我做错了什么?
我还不能添加评论...所以:
在 NewsPageViewModel 的构造函数中,您初始化了一个新的(但为空)ObservableCollection。
如果您不在 GetPost 方法中添加元素,_posts 将保持为空。
如果您想继续切换集合,NewsPageViewModel
必须实现 INotifyPropertyChanged
并在更改集合实例时引发 PropertyChanged
。这是怎么回事。我还在下面提供了一个更简单的 "quick fix" 解决方案。
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 必须知道要监听哪个集合的变化。
我有这个页面: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>
页面的数据上下文绑定到视图模型。 PageViewmModel
ItemsControl
数据模板是一个 Post
控件。
页面上ItemsControl
的ItemsSource
绑定到viewmodel的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 },
}
}
};
}
ItemsControl
显示为空。
我做错了什么?
我还不能添加评论...所以:
在 NewsPageViewModel 的构造函数中,您初始化了一个新的(但为空)ObservableCollection。
如果您不在 GetPost 方法中添加元素,_posts 将保持为空。
如果您想继续切换集合,NewsPageViewModel
必须实现 INotifyPropertyChanged
并在更改集合实例时引发 PropertyChanged
。这是怎么回事。我还在下面提供了一个更简单的 "quick fix" 解决方案。
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 必须知道要监听哪个集合的变化。