Ton*_*nti 2 .net c# data-binding collections wpf
我是 WPF 中数据绑定的新手,需要一些帮助。
A 有一个常规类,其中有一个 List 成员。我需要显示一个包含所有这些项目的列表框,并在将项目添加到该成员时进行更新。
我这样做的正确流程是什么?我尝试将 ListBox 绑定到 ObservableCollection。这种方法之所以有效,是因为每当我向 ObservableCollection 添加某些内容时,列表框都会更新,但是,这些添加不会保留到列表中。如何将 ObservableCollection“绑定”到列表,以便当我向 ObservableCollection 添加某些内容时,我真的将其添加到列表中?
提前致谢!
小智 6
ObservableCollection 具有采用 IEnumerable 的构造函数
ObservableCollection<int> myCollection = new ObservableCollection<int>(myList);
Run Code Online (Sandbox Code Playgroud)
因此,您可以在列表上创建一个 ObservableCollection 并仅对此集合进行操作。完成所有操作后,您可以将 ObservableCollection 转换回 List。
但更简单的方法是用 ObservableCollection 替换原始 List 并直接绑定到它。
如果需要更改原始列表,您必须编写实现 INotifyCollectionChanged 的包装器。
你可以试试我的代码片段:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
namespace ObservableCollectionListCheck
{
class Program
{
static void Main(string[] args)
{
var list = new List<string>();
var oc = new ObservableWrapper<string>(list);
oc.CollectionChanged += OnCollectionChanged;
list.AddRange(new [] {"1","2","3"});
Console.WriteLine($"List: {string.Join(" ",list)}");
Console.WriteLine($"ObservableWrapper: {string.Join(" ", oc)}");
oc.Add("4");
Console.WriteLine($"List: {string.Join(" ", list)}");
Console.WriteLine($"ObservableWrapper: {string.Join(" ", oc)}");
list.Add("5"); // OnCollectionChanged will not call
Console.WriteLine($"List: {string.Join(" ", list)}");
Console.WriteLine($"ObservableWrapper: {string.Join(" ", oc)}");
Console.ReadLine();
}
private static void OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
Console.WriteLine($"OnCollectionChanged:{notifyCollectionChangedEventArgs.Action}");
}
}
public class ObservableWrapper<T> : IList<T>, INotifyCollectionChanged
{
private readonly IList<T> _internalList;
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void RaiseCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
CollectionChanged?.Invoke(sender, args);
}
public ObservableWrapper(IList<T> list)
{
_internalList = list;
}
public IEnumerator<T> GetEnumerator()
{
return _internalList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
_internalList.Add(item);
RaiseCollectionChanged(this,new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,item));
}
public void Clear()
{
_internalList.Clear();
RaiseCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public Boolean Contains(T item)
{
return _internalList.Contains(item);
}
public void CopyTo(T[] array, Int32 arrayIndex)
{
_internalList.CopyTo(array,arrayIndex);
}
public Boolean Remove(T item)
{
var result = _internalList.Remove(item);
RaiseCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
return result;
}
public Int32 Count => _internalList.Count;
public Boolean IsReadOnly => false;
public Int32 IndexOf(T item) => _internalList.IndexOf(item);
public void Insert(Int32 index, T item)
{
_internalList.Insert(index,item);
RaiseCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,item,index));
}
public void RemoveAt(Int32 index)
{
_internalList.RemoveAt(index);
RaiseCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, _internalList[index], index));
}
public T this[Int32 index]
{
get { return _internalList[index]; }
set { _internalList[index] = value; }
}
}
}
Run Code Online (Sandbox Code Playgroud)