C# 绑定的ObservableCollection更改时ListView未更新
我正在开发一个搜索窗口,该窗口将搜索结果加载到ObservableCollection中,然后使用ListView显示结果 搜索完成后,将ListView的ItemSource设置为ObservableCollection将正确填充列表 我试图让ListView在搜索添加其他结果时更新,但是ListView根本没有填充任何数据。我想不出我的装订在哪里掉了 我的研究显示了使用DataContext的各种方法,尽管似乎没有任何一种方法能起到帮助作用;我尝试使用CodeBehind以及xaml窗口级别将其分配给“this”和CachedData类 抱歉,代码太长了,我留下了一些我认为可能有助于为问题添加上下文的内容 XAML:C# 绑定的ObservableCollection更改时ListView未更新,c#,wpf,xaml,listview,data-binding,C#,Wpf,Xaml,Listview,Data Binding,我正在开发一个搜索窗口,该窗口将搜索结果加载到ObservableCollection中,然后使用ListView显示结果 搜索完成后,将ListView的ItemSource设置为ObservableCollection将正确填充列表 我试图让ListView在搜索添加其他结果时更新,但是ListView根本没有填充任何数据。我想不出我的装订在哪里掉了 我的研究显示了使用DataContext的各种方法,尽管似乎没有任何一种方法能起到帮助作用;我尝试使用CodeBehind以及xaml窗口级别
MainWindow.xaml.cs中的代码隐藏:
private async void SearchAccount(string searchTerm, string searchField, string searchOperator)
{
//Create the string we'll use for searching
string urlString = "Stuff";
//Create an ObservableCollection, then use it to blank the cache
ObservableCollection<Account> resultsList = new ObservableCollection<Account>();
CachedData.accounts = resultsList;
//Getting data from the search using an XML Reader
XmlReader resultsReader = null;
try
{
//Using XmlReader to grab the search results from SLX
XmlUrlResolver resultsResolver = new XmlUrlResolver();
resultsResolver.Credentials = LoginCredentials.userCred;
XmlReaderSettings resultsReaderSettings = new XmlReaderSettings();
resultsReaderSettings.XmlResolver = resultsResolver;
resultsReaderSettings.Async = true;
resultsReader = XmlReader.Create(urlString, resultsReaderSettings);
}
catch (Exception error)
{
}
//Grabbing data from the XML and storing it, hopefully updating the ListView as we go
using (resultsReader)
{
while (await resultsReader.ReadAsync())
{
while (resultsReader.ReadToFollowing("slx:Account"))
{
//Setting data from the XML to a new Account object ready to be passed to the list
Account account = new Account();
account.GUID = new Guid();
resultsReader.MoveToFirstAttribute(); account.SDataKey = resultsReader.Value;
resultsReader.ReadToFollowing("slx:AccountName"); account.AccountName = resultsReader.ReadElementContentAsString();
CachedData.accounts.Add(account);
//--Uncommenting this gives odd results;
//--The first item is displayed, any others aren't.
//--If there are a lot of items, the application eventually errors like mad and ends.
//--Looks like one error window for each item, though I don't see the message before they die along with the application.
//accountSearchResultsListView.ItemsSource = CachedData.accounts;
}
}
}
//--Uncommenting this works but shows the data once the entire XML has been read through, which can take some time so isn't ideal.
//accountSearchResultsListView.ItemsSource = CachedData.accounts; }
private async void SearchAccount(字符串searchTerm、字符串searchField、字符串searchOperator)
{
//创建用于搜索的字符串
字符串urlString=“Stuff”;
//创建一个ObservableCollection,然后使用它清空缓存
ObservableCollection resultsList=新的ObservableCollection();
CachedData.accounts=结果列表;
//使用XML读取器从搜索中获取数据
XmlReader resultsReader=null;
尝试
{
//使用XmlReader从SLX获取搜索结果
XmlUrlResolver Resolver=新的XmlUrlResolver();
resultsResolver.Credentials=LoginCredentials.userCred;
XmlReaderSettings resultsReaderSettings=新的XmlReaderSettings();
resultsReaderSettings.XmlResolver=resultsResolver;
resultsReaderSettings.Async=true;
resultsReader=XmlReader.Create(urlString,resultsReaderSettings);
}
捕获(异常错误)
{
}
//从XML中获取数据并将其存储,希望在执行时更新ListView
使用(结果阅读器)
{
while(等待resultsReader.ReadAsync())
{
while(resultsReader.ReadToFollowing(“slx:Account”))
{
//将数据从XML设置为准备传递到列表的新帐户对象
账户=新账户();
account.GUID=新GUID();
resultsReader.MoveToFirstAttribute();account.SDataKey=resultsReader.Value;
resultsReader.ReadToFollow(“slx:AccountName”);account.AccountName=resultsReader.ReadElementContentAsString();
CachedData.accounts.Add(account);
//--取消注释会产生奇怪的结果;
//--将显示第一个项目,而不显示任何其他项目。
//--如果有很多项,应用程序最终会出错,如mad并结束。
//--看起来每个项目都有一个错误窗口,但在它们随应用程序一起消失之前,我看不到消息。
//accountSearchResultsListView.ItemsSource=CachedData.accounts;
}
}
}
//--取消注释会起作用,但在读取整个XML后会显示数据,这可能需要一些时间,因此并不理想。
//accountSearchResultsListView.ItemsSource=CachedData.accounts;}
类引用,存储在单独的.cs文件中,但位于同一命名空间下:
public class CachedData
{
public static ObservableCollection<Account> accounts { get; set; }
public static event PropertyChangedEventHandler PropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged = delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
}
public class Account : IEquatable<Account>
{
public Guid GUID { get; set; }
public string SDataKey { get; set; }
public string AccountName { get; set; }
public override string ToString()
{
return AccountName;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
Account objAsPart = obj as Account;
if (objAsPart == null) return false;
else return Equals(objAsPart);
}
public override int GetHashCode()
{
return 0;
}
public bool Equals(Account other)
{
if (other == null) return false;
return (GUID.Equals(other.GUID));
}
}
公共类缓存数据
{
公共静态ObservableCollection帐户{get;set;}
公共静态事件属性ChangedEventHandler属性Changed;
公共静态事件EventHandler StaticPropertyChanged=委托{};
私有静态void NotifyStaticPropertyChanged(字符串propertyName)
{
StaticPropertyChanged(空,新PropertyChangedEventArgs(propertyName));
}
}
公共类帐户:IEquatable
{
公共Guid Guid{get;set;}
公共字符串SDataKey{get;set;}
公共字符串AccountName{get;set;}
公共重写字符串ToString()
{
返回帐户名;
}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)返回false;
账户objAsPart=作为账户的obj;
if(objAsPart==null)返回false;
否则返回等于(objAsPart);
}
公共覆盖int GetHashCode()
{
返回0;
}
公共bool等于(其他账户)
{
if(other==null)返回false;
返回(GUID.Equals(other.GUID));
}
}
我感谢您提供的任何帮助,这已经困扰了我好几天了。当您在xaml中设置数据绑定时,应用程序启动时存在的ObservableCollection实例将被绑定。因此,请在应用程序启动之前实例化一个实例,不要用新实例替换它,除非您在代码隐藏中重置了数据绑定。如果需要清除其元素,请使用clear方法。问题是您正在使用ObservableCollection,它在内部实现了INotifyCollectionChanged。这并不会引发对集合的所有更改。只有在从收藏中添加或删除项目时,才会引发收藏更改。 因此,如果有人分配了一个新的集合实例(,如您的情况所示,),就会出现问题。因此,重置绑定并不是一个很好的选择,相反,您可以自己进行更改。通过简单地实现INotifyPropertyChanged(通常情况下)
公共类数据类:INotifyPropertyChanged
{
公共事件属性ChangedEventHandler本体
public class CachedData
{
public static ObservableCollection<Account> accounts { get; set; }
public static event PropertyChangedEventHandler PropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged = delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
}
public class Account : IEquatable<Account>
{
public Guid GUID { get; set; }
public string SDataKey { get; set; }
public string AccountName { get; set; }
public override string ToString()
{
return AccountName;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
Account objAsPart = obj as Account;
if (objAsPart == null) return false;
else return Equals(objAsPart);
}
public override int GetHashCode()
{
return 0;
}
public bool Equals(Account other)
{
if (other == null) return false;
return (GUID.Equals(other.GUID));
}
}
public class DataClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private ObservableCollection<string> collection;
public ObservableCollection<string> Collection
{
get { return collection; }
set
{
collection = value;
OnPropertyChanged("Collection");
}
}
}