需要具有排序和过滤的相同BindingList的多个视图 - WPF

时间:2013-12-10 12:22:41

标签: c# wpf binding collections

我知道这与已经提出的其他问题非常相似,而且我已经查看了它们,但是在某种程度上解决方案不适合这种特定情况。

我在BindingList中有一组对象:

private BindingList<PathologyModel> _patientPathologies;
public BindingList<PathologyModel> PatientPathologies { get { return _patientPathologies; } }

此集合需要绑定到不同的XamDataGrid控件(Infragistics的DataGrid版本)。我需要使用BindingList,因为我需要知道用户何时编辑集合中的特定项目,其他类型的集合似乎不支持。

我需要对集​​合进行排序,所以现在每次从列表中添加/删除项目时我都必须这样做:

    private void Pathologies_ListChanged(object sender, ListChangedEventArgs e)
    {
        if (e.ListChangedType == ListChangedType.ItemAdded || e.ListChangedType == ListChangedType.ItemDeleted)
        {
            _pathologies = new BindingList<PathologyModel>(_pathologies.OrderBy(x => x.Tooth.ToToothNumber()).ThenBy(x => x.DiagnosisDate).ToList());
        }
    }

如果没有额外的复制可以自动完成,那将是很好的。但这不是我现在最大的问题。

我需要不同的XamDataGrids来拥有同一个集合的不同过滤视图,目前我正在实现这一点:

    public ICollectionView AllPathologies { get { return CollectionViewSource.GetDefaultView(PatientPathologies); } }

    public ICollectionView TodaysPathologies { get { return CollectionViewSource.GetDefaultView(PatientPathologies.Where(x => x.DiagnosisDate.Date == DateTime.Today.Date)); } }

几乎有效...我说几乎是因为视图显示的是正确的数据,但最后的要求是我还需要跟踪CurrentItemChanged事件,以便我可以启用/禁用某些操作取决于用户所在的记录。这可以在AllPathologies视图中正常工作,但是不会被TodaysPathologies引发,我猜是因为每次访问该属性时它都会获得一个不同的集合源副本?奇怪的是,ListItem_Changed事件仍然可以对原始集合源正常工作。

我已尝试制作私有的CollectionViewSource对象来支持ICollectionView属性,正如我在其他文章中看到的那样,例如:

private CollectionViewSource _todaysPathologies;
public ICollectionView TodaysPathologies { get { return _todaysPathologies.View; } }

...
_todaysPathologies = new CollectionViewSource{Source= _patientPathologies}.View;

但由于源是BindingList,我无法应用过滤谓词:

TodaysPathologies.CanFilter <--- false

所以现在我被卡住了。亲爱的StackOverflowers,我把命运掌握在你手中。

1 个答案:

答案 0 :(得分:0)

“我需要知道用户何时编辑集合中的特定项目,其他类型的集合似乎不支持。”

这不完全正确。在继承自INotifyPropertyChanged的类中使用的集合将解决此问题。

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

我建议在你的窗口页面中创建一个内部类。使用每个值的属性和可编辑属性将调用NotifyPropertyChanged事件。然后,您将拥有这些内部类对象的集合。内部类将表示网格中的一行。

我之前解决此问题的另一种方法是指定用户输入信息的文本列:

在XAML中:

<DataGridTextColumn //... Binding="{Binding Path=Value, Mode=TwoWay}">
    <DataGridTextColumn.EditingElementStyle>
         <Style TargetType="TextBox"/>
    </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>

在代码中:

private string value;
public string Value
        {
            get
            { return value; }
            set
            {
                this.value = value;
                NotifyPropertyChanged("Value");
            }
        }

内部类包含此Value属性以及对我曾经拥有的集合的类的对象的引用。

现在我有了这个内部类的对象集合,它们都存储了这两个对象。我用它来显示类的信息,并有一个额外的列来添加一个值。然后我用旧的类信息+这个值创建一个新对象。

如果您发现这有用,并希望我详细介绍,请告诉我。我很乐意。那或某人会张贴:P