Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 绑定的ObservableCollection更改时ListView未更新_C#_Wpf_Xaml_Listview_Data Binding - Fatal编程技术网

C# 绑定的ObservableCollection更改时ListView未更新

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窗口级别

我正在开发一个搜索窗口,该窗口将搜索结果加载到ObservableCollection中,然后使用ListView显示结果

搜索完成后,将ListView的ItemSource设置为ObservableCollection将正确填充列表

我试图让ListView在搜索添加其他结果时更新,但是ListView根本没有填充任何数据。我想不出我的装订在哪里掉了

我的研究显示了使用DataContext的各种方法,尽管似乎没有任何一种方法能起到帮助作用;我尝试使用CodeBehind以及xaml窗口级别将其分配给“this”和CachedData类

抱歉,代码太长了,我留下了一些我认为可能有助于为问题添加上下文的内容

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");
        }
    }       
}