我有一个ObservableCollection< RSSFeed> ;,应用程序启动项从UI线程添加到此集合中. RSSFeed的属性绑定到WPF ListView.后来,我想异步更新每个RSSFeed.所以我正在考虑实现像RSSFeed.FetchAsync()这样的东西,并在其更新的属性上提升PropertyChanged. 我知道ObservableCollection不支持来自UI线程以外的线程的更新,它会抛出NotSupportedException.但是因为我没有操纵ObservableCollection本身而是更新其项目的属性,我可以期待这个工作并看到ListView项目更新吗?或者由于PropertyChanged它会抛出异常吗? 编辑:代码 RSSFeed.cs
public class RSSFeed { public String Title { get; set; } public String Summary { get; set; } public String Uri { get; set; } public String Encoding { get; set; } public List<FeedItem> Posts { get; set; } public bool FetchedSuccessfully { get; protected set; } public RSSFeed() { Posts = new List<FeedItem>(); } public RSSFeed(String uri) { Posts = new List<FeedItem>(); Uri = uri; Fetch(); } public void FetchAsync() { // call Fetch asynchronously } public void Fetch() { if (Uri != "") { try { MyWebClient client = new MyWebClient(); String str = client.DownloadString(Uri); str = Regex.Replace(str,"<!--.*?-->",String.Empty,RegexOptions.Singleline); FeedXmlReader reader = new FeedXmlReader(); RSSFeed feed = reader.Load(str,new Uri(Uri)); if (feed.Title != null) Title = feed.Title; if (feed.Encoding != null) Encoding = feed.Encoding; if (feed.Summary != null) Summary = feed.Summary; if (feed.Posts != null) Posts = feed.Posts; FetchedSuccessfully = true; } catch { FetchedSuccessfully = false; } } }
UserProfile.cs
public class UserProfile : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public event CollectionChangeEventHandler CollectionChanged; private ObservableCollection<RSSFeed> feeds; public ObservableCollection<RSSFeed> Feeds { get { return feeds; } set { feeds = value; OnPropertyChanged("Feeds"); } } public UserProfile() { feeds = new ObservableCollection<RSSFeed>(); } protected void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this,new PropertyChangedEventArgs(name)); } } protected void OnCollectionChanged(RSSFeed feed) { CollectionChangeEventHandler handler = CollectionChanged; if (handler != null) { handler(this,new CollectionChangeEventArgs(CollectionChangeAction.Add,feed)); } } }
MainWindow.xaml.cs
public partial class MainWindow : Window,INotifyPropertyChanged { // My ListView is bound to this // ItemsSource="{Binding Posts} public List<FeedItem> Posts { get { if (listBoxChannels.SelectedItem != null) return ((RSSFeed)listBoxChannels.SelectedItem).Posts; else return null; } } private void Window_Loaded(object sender,RoutedEventArgs e) { // here I load cached feeds // called from UI thread // now I want to update the feeds // since network operations are involved,// I need to do this asynchronously to prevent blocking the UI thread } }
谢谢.
解决方法
否则,从后台线程更新属性将起作用,但如果您正在过滤或排序ObservableCollection,则除非引发了某些集合更改通知事件,否则不会重新应用过滤器.
您可以通过查找集合中项目的索引(例如,通过将其报告为progresspercentage)并设置list.item(i)= e.userstate来重新应用过滤器和排序,即单独替换列表中的项目在ProgressChanged事件中.这样,将保留绑定到集合的任何控件的SelectedItem,而过滤器和排序将遵循项中任何更改的值.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。