Re: [问题] 客制化CollectionViewGroup

楼主: name2name2 (yang~hi)   2017-10-07 00:14:24
今天再试了一下,
用原程式码 https://pastebin.com/GEJ5yMWd ,
改两个地方能够做到更新:
1. 在addItem_Click加上Refresh的动作:
private void addItem_Click(object sender, RoutedEventArgs e)
{
//有增加进去, 但是UI不会新增这一笔1983的资料
Employees.Add(new Employee
{
FirstName = "FirstName10",
LastName = "LastName10",
HireDate = new DateTime(1983, 1, 1)
});
var s =
((CollectionViewSource)this.FindResource("EmployeesSource"));
s.View.Refresh();
}
2. 以及将 EmployeeCollectionView改写为:
class EmployeeCollectionView : ListCollectionView
{
private readonly IEnumerable<EmployeeCollectionViewGroup> _groups;
public override ReadOnlyObservableCollection<object> Groups
{
get { return new ReadOnlyObservableCollection<object>(new
ObservableCollection<object>(_groups)); }
}
public EmployeeCollectionView(IList list)
: base(list)
{
_groups = list
.OfType<Employee>()
.GroupBy(x => x.HireDate)
.Select(x => new EmployeeCollectionViewGroup(x.Key, x));
}
}
测试可以有更新UI的效果
更改说明:
我后来试了一下,UI上员工分群资料实际上是取用EmployeeCollectionView的Groups,
而如果要更新UI,在集合变动的时候,
应该至少会引发Groups的get动作,
但是原程式码下中断点在get,当按下add按钮不会引发get
我观察一般的Binding,
WPF在集合有变动时会自动内部帮你再引发get一次
不过我猜自定义CollectionView时不知少了什么东西,所以这个重get机制没办法运作
目前只找到第一点主动Refresh的方式让他引发get
可以引发get后,原程式码的写法
public EmployeeCollectionView(IList list)
: base(list)
{
_groups = list
.OfType<Employee>()
.GroupBy(x => x.HireDate)
.Select(x => new EmployeeCollectionViewGroup(x.Key, x))
.ToList();
这边建构式会把Source绑定的Employees传进来,
但最后的ToList应有产生一个新List的效果,
因此_groups变成取产生的新List而不是Employees的参考,
导致Employees变动时,_groups的值不会跟着变动
上方第二点改写去掉ToList,让_groups保持取得Employees的参考并分组的集合,
在get时相当于将变动后的Employees分组回传,就能反映出Employees的变动到UI上
不知这样做法如何
(目前还不知道如何不透过Refresh就可以在集合变动时让他重Get)
补充1:
刚想到一个更简洁的方式,
可以把Refresh的动作加到Employees.CollectionChanged,
其他地方只需对集合做增删即可引发CollectionChanged的Refresh,
不需重复写Refresh
在建构式写上
public Window2()
{
InitializeComponent();
//初始化这边可以加到UI上
Employees = new ObservableCollection<Employee>
{
new Employee { FirstName = "FirstName1", LastName =
"LastName1", HireDate = new DateTime(1970, 1, 1) },
........
};
Employees.CollectionChanged += Employees_CollectionChanged;
DataContext = this;
}
及 Employees_CollectionChanged:
private void Employees_CollectionChanged
(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
((CollectionViewSource)this.FindResource("EmployeesSource")).View.Refresh();
}
: : 各位好,
: : 我有资料需要分组, 所以我用了listbox 搭配CollectionViewSource的group去分类
: : group heaer的layout有一个delete的image可以删除整个group
: : 但是现在有需求是如果目前正在删除中,
: : 这个delete image要把他disable 或是 隐藏起来
: : 所以我在delete image的tag属性让它bing住group item本身,
: : 这样我在delete image 按下时可以拿到group item的datacontext是CollectionViewGroup
: : 所以我想客制化CollectionViewGroup, 多加一个属性进去CollectionViewGroup去控制
: : delete image的visibility
: : 找到网络上有人做类似的客制化
: : 但我目前遇到如果我动态增加一笔资料时, UI就不会更新,
: : 不知道是哪边漏了实作, 希望有人帮我解答或是什么关键字可以找到资料, 谢谢各位
: : 程式码
: : https://pastebin.com/GEJ5yMWd

Links booklink

Contact Us: admin [ a t ] ucptt.com