CollectionView就是一个视图类,它的实例代表了一个视图类实例,视图可以用来做集合对象显示的相关操作(分组,排序,过滤,导航等)。视图的优点有:对视图的分组,过滤等等操作不会影响到源集合本身;一个集合可以有多个不同的视图,源集合的改变有能力通知到它所有的视图(前提是源集合实现了INotifyCollectionChanged接口)。
CollectionViewSource是CollectionView类针对XAML的一个代理类。对CollectionViewSource的操作和对其XAML的设置最终会被应用到它的CollectionView上。
/// <summary>
/// 大数据定位、过滤等集成封装对象
/// </summary>
private MainVM<DemoDto> _vm;
#### 初始化
_vm = new MainVM<PklResponseDtoEx>();
_vm.CollectionView.Culture = System.Globalization.CultureInfo.CurrentCulture;
// 当前项同步
DataGrid1.IsSynchronizedWithCurrentItem = true;
DataGrid1.ItemsSource = _vm.CollectionView;
#### 过滤
_vm.CollectionView.Filter = (obj) =>
{
var dto = obj as DemoDto;
return (bool)(dto != null);
};
#### 更新数据,异步操作,防止跨线程
ThreadPool.QueueUserWorkItem(delegate
{
SynchronizationContext.SetSynchronizationContext(new
System.Windows.Threading.DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
SynchronizationContext.Current.Post(pl =>
{
//里面写真正的业务内容
_vm.Clear();
foreach (DemoDto item in response.Body.ResultList)
{
_vm.Add(item);
}
_vm.CollectionView.Refresh();
}, null);
});
#### 定位
_mainThreadSynContext.Post(new SendOrPostCallback(state =>
{
var selected = _vm.FirstOrDefault(x => x.Guid == pklGuid);
if (selected != null)
{
_vm.CollectionView.MoveCurrentTo(selected);
dgData.ScrollIntoView(selected);
}
}), null);
#### 取消排序
_vm.CollectionView.SortDescriptions.Clear();
this.Dispatcher.Invoke(() =>
{
foreach (var column in DataGrid1.Columns)
{
column.SortDirection = null;
}
});
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
/// <summary>
/// 增加、删除元素时UI会更新,
/// 修改属性时更新,需要 T 继承NotifyPropertyChanged
/// </summary>
/// <typeparam name="T"></typeparam>
public class MainVM<T>
{
/// <summary>
/// 数据列表
/// </summary>
private readonly ObservableRangeCollection<T> _data;
public MainVM()
{
_data = new ObservableRangeCollection<T>();
}
/// <summary>
/// 列表视图
/// </summary>
public ICollectionView CollectionView => System.Windows.Data.CollectionViewSource.GetDefaultView(_data);
public T FirstOrDefault(Func<T, bool> predicate)
{
return _data.FirstOrDefault(predicate);
}
public void Add(T item)
{
_data.Add(item);
}
public void AddRange(IEnumerable<T> collection)
{
if (collection == null)
{
return;
}
_data.AddRange(collection);
}
public void Remove(T item)
{
_data.Remove(item);
}
public void RemoveRange(IEnumerable<T> collection)
{
_data.RemoveRange(collection);
}
public void Replace(T item)
{
_data.Replace(item);
}
public void ReplaceRange(IEnumerable<T> collection)
{
_data.ReplaceRange(collection);
}
public void Clear()
{
_data.Clear();
}
public int Count()
{
return _data.Count;
}
/// <summary>
/// 可批量处理通知类
/// </summary>
/// <typeparam name="Titem"></typeparam>
class ObservableRangeCollection<Titem> : ObservableCollection<Titem>
{
public ObservableRangeCollection() : base() { }
public ObservableRangeCollection(IEnumerable<Titem> collection) : base(collection) { }
public void AddRange(IEnumerable<Titem> collection)
{
if (collection == null)
{
return;
}
foreach (var item in collection)
{
Items.Add(item);
}
OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
}
public void RemoveRange(IEnumerable<Titem> collection)
{
if (collection == null)
{
return;
}
foreach (var item in collection)
{
Items.Remove(item);
}
OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
}
public void Replace(Titem item)
{
ReplaceRange(new Titem[] { item });
}
public void ReplaceRange(IEnumerable<Titem> collection)
{
if (collection == null)
{
return;
}
Items.Clear();
foreach (var item in collection)
{
Items.Clear();
}
OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
}
}
}