GVKun编程网logo

在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?

25

在这里,我们将给大家分享关于在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?的知识,同时也会涉及到如何更有效地.net–windowsmetroapp中的Collec

在这里,我们将给大家分享关于在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?的知识,同时也会涉及到如何更有效地.net – windows metro app中的CollectionViewSource、c# – WPF将已过滤的ObservableCollection ICollectionView绑定到Combobox、c# – 可观察的CollectionViewSource、c# – 在MVVM世界中更改CollectionViewSource Source的内容。

本文目录一览:

在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?

在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?

主题确实说明了一切。

<CollectionViewSource x:Key="MyData"    Source="{Binding}" Filter="{ SomethingMagicInXaml? }" />

这并不是说我没有代码。它只是在me我。

答案1

小编典典

如果您“足够努力”,直到在其中编写整个程序,您都可以在XAML中执行几乎所有操作。

您永远不会回避代码(嗯,如果您使用库,则不必编写任何代码,但是应用程序当然仍然依赖它),这是在这种特定情况下可以执行的示例:

<CollectionViewSource x:Key="Filtered" Source="{Binding DpData}"                      xmlns:me="clr-namespace:Test.MarkupExtensions">    <CollectionViewSource.Filter>        <me:Filter>            <me:PropertyFilter PropertyName="Name" Value="Skeet" />        </me:Filter>    </CollectionViewSource.Filter></CollectionViewSource>using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Markup;using System.Windows.Data;using System.Collections.ObjectModel;using System.Windows;using System.Text.RegularExpressions;namespace Test.MarkupExtensions{    [ContentProperty("Filters")]    class FilterExtension : MarkupExtension    {        private readonly Collection<IFilter> _filters = new Collection<IFilter>();        public ICollection<IFilter> Filters { get { return _filters; } }        public override object ProvideValue(IServiceProvider serviceProvider)        {            return new FilterEventHandler((s, e) =>                {                    foreach (var filter in Filters)                    {                        var res = filter.Filter(e.Item);                        if (!res)                        {                            e.Accepted = false;                            return;                        }                    }                    e.Accepted = true;                });        }    }    public interface IFilter    {        bool Filter(object item);    }    // Sketchy Example Filter    public class PropertyFilter : DependencyObject, IFilter    {        public static readonly DependencyProperty PropertyNameProperty =            DependencyProperty.Register("PropertyName", typeof(string), typeof(PropertyFilter), new UIPropertyMetadata(null));        public string PropertyName        {            get { return (string)GetValue(PropertyNameProperty); }            set { SetValue(PropertyNameProperty, value); }        }        public static readonly DependencyProperty ValueProperty =            DependencyProperty.Register("Value", typeof(object), typeof(PropertyFilter), new UIPropertyMetadata(null));        public object Value        {            get { return (object)GetValue(ValueProperty); }            set { SetValue(ValueProperty, value); }        }        public static readonly DependencyProperty RegexPatternProperty =            DependencyProperty.Register("RegexPattern", typeof(string), typeof(PropertyFilter), new UIPropertyMetadata(null));        public string RegexPattern        {            get { return (string)GetValue(RegexPatternProperty); }            set { SetValue(RegexPatternProperty, value); }        }        public bool Filter(object item)        {            var type = item.GetType();            var itemValue = type.GetProperty(PropertyName).GetValue(item, null);            if (RegexPattern == null)            {                return (object.Equals(itemValue, Value));            }            else            {                if (itemValue is string == false)                {                    throw new Exception("Cannot match non-string with regex.");                }                else                {                    return Regex.Match((string)itemValue, RegexPattern).Success;                }            }        }    }}

如果您想在XAML中做某事,标记扩展是您的朋友。

(您可能想拼写扩展名,即me:FilterExtension,由于Visual
Studio中的动态检查可能会毫无理由地抱怨,它当然仍会编译和运行,但警告可能会令人讨厌。
也不要指望CollectionViewSource.Filter扩展名。出现在IntelliSense中,它不希望您通过XML-element-
notation设置该处理程序)

.net – windows metro app中的CollectionViewSource

.net – windows metro app中的CollectionViewSource

我有一个集合,我需要3个不同的视图
1.所有收集数据
2.分组数据(分组标准将在应用程序生命周期中修改)
3.过滤的数据(过滤条件将在应用程序生命周期中修改)

我想要的是所有视图都应该绑定到同一个集合,以便对集合的任何更改都应该同步到所有视图.

使用WPF,可以使用CollectionViewSource实现.
在Modern UI应用程序中,CollectionViewSource仍然存在,但功能有限.它没有SortDescription和FilterDescription.

如何在Modern UI应用程序中实现收集同步?

解决方法

显然,要求您在WinRT中使用LINQ执行排序,分组和过滤. CollectionViewSource似乎只提供在控件之间共享的公共视图.

Source

c# – WPF将已过滤的ObservableCollection ICollectionView绑定到Combobox

c# – WPF将已过滤的ObservableCollection ICollectionView绑定到Combobox

我想根据类型(类型AddPoint)过滤ObservableCollection到一个子集,并希望它按升序排序,没有重复.我的基类是ModelBase,w /子类AddPoint,Time,Repeat等…… ObservableCollection MotionSequenceCollection将以任何顺序填充这些类型,有些将是重复的.

我已经尝试了几次不同的时间,并在ICollectionView属性中显示它,我从’Bind subset of collection中拉出’.

可观察的收藏品

private ObservableCollection<ModelBase> _motionSequenceCollection = 
        new ObservableCollection<ModelBase>();

    public ObservableCollection<ModelBase> MotionSequenceCollection
    {
        get
        {
            return _motionSequenceCollection;
        }

        set
        {
            if (_motionSequenceCollection == value)
            {
                return;
            }

            var oldValue = _motionSequenceCollection;
            _motionSequenceCollection = value;

            // Update bindings,no broadcast
            RaisePropertyChanged();
        }
    }

    public ICollectionView Location
    {
        get
        {
             var location = CollectionViewSource.Getdefaultview(_motionSequenceCollection);

            //DOES NOT WORK.  PROBLEM: GetType() creates type of system.type() and AddPoint,which don't work.  Need a cast,or something??  
            // found at https://stackoverflow.com/questions/9621393/bind-subset-of-collection  The problem is that there is an error:
            //    Cannot apply operator '==' to operands of type 'System.Type' and 'MotionSeq.Model.AddPoint',//    candidates are:
            //          bool ==(System.Reflection.MemberInfo,System.Reflection.memberInfo) (in class MemberInfo)
            //          bool ==(System.type,System.Type) (in class Type)
            //location.Filter = p => (p as ModelBase).GetType() == AddPoint;

            //DOES NOT WORK.  PROBLEM: Affects the main collection and won't let TIME type added.
            //location.Filter = o1 => (o1 is AddPoint);

            //DOES NOT WORK.  PROBLEM: Sorts fine,but also sorts MotionSequenceCollection!!  What up w/ that!?  
            //location.sortDescriptions.Add(new SortDescription("AddPointClassName",ListSortDirection.Ascending));

            //DOES NOT WORK.  PROBLEM: MotionSequenceCollection does not update.
            //location.Filter = p => (p as ModelBase) == AddPoint;

            //DOES NOT WORK.  PROBLEM: Source is not instantiated(?) and exmaple from stackoverflow and not sure how that got there in the first place.
            //source.Filter = p => (p as ModelBase).GetType() == "AddPoint";
            //return source;

            return location;
        }
    }

解决方法

All collections have a default CollectionView. WPF always binds to a view rather than a collection. If you bind directly to a collection,WPF actually binds to the default view for that collection. This default view is shared by all bindings to the collection,which causes all direct bindings to the collection to share the sort,filter,group,and current item characteristics of the one default view.

尝试创建CollectionViewSource并设置其过滤逻辑,如下所示:

//create it as static resource and bind your ItemsControl to it
<CollectionViewSource x:Key="csv" Source="{StaticResource MotionSequenceCollection}" 
                  Filter="CollectionViewSource_Filter">
    <CollectionViewSource.GroupDescriptions>
       <PropertyGroupDescription PropertyName="YYY"/>
    </CollectionViewSource.GroupDescriptions>
    <CollectionViewSource.sortDescriptions>
         <scm:SortDescription PropertyName="YYY" Direction="Ascending"/>
    </CollectionViewSource.sortDescriptions>
</CollectionViewSource> 

private void CollectionViewSource_Filter(object sender,FilterEventArgs e)
{
    var t = e.Item as ModelBase;
    if (t != null)

    {
        //use your filtering logic here

    }
}

c# – 可观察的CollectionViewSource

c# – 可观察的CollectionViewSource

我正在尝试设置一个ListBox,从CollectionViewSource获取它的数据.我想要发生的是,当我更新底层数据源时,ListBox也会更新.我的Xaml看起来像这样……

<Window.Resources>
    <ObjectDataProvider x:Key="AppTests" ObjectType="{x:Type Application:AppTestProvider}" MethodName="GetAppTests" />
    <CollectionViewSource x:Key="cvs" Source="{StaticResource AppTests}">
        <CollectionViewSource.sortDescriptions>
            <scm:SortDescription PropertyName="Priority" Direction="Ascending" />
        </CollectionViewSource.sortDescriptions>
    </CollectionViewSource>
</Window.Resources>

<Grid>
    <ListBox x:Name="TestList" ItemsSource="{Binding Source={StaticResource cvs}}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding TestName}" />                    
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

这显示数据正常但如果我更改基础数据,那么更改不会出现在网格上,直到我在后面的代码中调用cvs.View.Refresh()方法.

如何让这个“可观察”,以便自动发生变化?

注意:使用CVS的原因是基于底层对象中的属性为列表提供排序.

解决方法

要查看对集合本身所做的更改(例如添加和删除项),集合应实现INotifyCollectionChanged(ObservableCollection是此接口的基本实现).要查看对集合中的项目所做的更改(例如,修改特定项目上的特定属性),您的项目对象应实现INotifyPropertyChanged.

CollectionViewSource是UI和实际集合之间的一个层,它提供了对集合显示方式的一些额外控制(排序,过滤,分组等).如果底层数据支持通知(通过实现上述接口),它只会将通知传递给UI.

c# – 在MVVM世界中更改CollectionViewSource Source

c# – 在MVVM世界中更改CollectionViewSource Source

编辑:我创建了一个新的VS2010 WPF应用程序,只有3个文件MainWindow.xaml,MainWindow.xaml.cs和MainWindowviewmodel.cs(下面列出).如果有人觉得非常有帮助,您可以在几秒钟内重新创建问题(复制/粘贴).当您运行应用程序时,DataGrid将显示错误的字符串“OldCollection”.如果将ItemsSource绑定更改为MyCollection,则显示“NewCollection”,这是正确的.

详细描述:
起初我有一个DataGrid,其ItemsSource绑定到MyCollection.我需要一个方法UpdateCollection来分配一个新的ObservableCollection<>到MyCollection.通过向MyCollection添加NotifyPropertyChange,UI更新.

接下来,有必要引入一个CollectionViewSource来启用分组.将UI绑定到MyCollectionView后,对UpdateCollection的调用现在无效.调试器确认MyCollectionView始终包含初始MyCollection.如何让我的NewCollection反映在View中?我尝试过View.Refresh(),绑定CollectionViewSource,以及无数其他策略.

注意:主要是其他人关注收集项目的更改而不更新视图(分组/排序)而不调用Refresh.我的问题是我正在为CollectionViewSource分配一个全新的集合,并且视图/ UI永远不会改变.

// MainWindow.xaml
<Window x:xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="grid" ItemsSource="{Binding MyCollectionView}" />
    </Grid>
</Window>

//MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace CollectionView
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowviewmodel();
        }
    }
}

//MainWindowviewmodel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;

namespace CollectionView
{
    class MainWindowviewmodel : INotifyPropertyChanged
    {
        public MainWindowviewmodel()
        {
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "OldCollection" } };

            MyCollectionViewSource = new CollectionViewSource();

            // Bind CollectionViewSource.source to MyCollection
            Binding MyBind = new Binding() { Source = MyCollection };
            BindingOperations.SetBinding(MyCollectionViewSource,CollectionViewSource.sourceProperty,MyBind);

            // The DataGrid is bound to this ICollectionView
            MyCollectionView = MyCollectionViewSource.View;

            // This assignment here to demonstrate that View/UI does not update to show "NewCollection"
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "NewCollection" } };
        }

        // Collection Property
        // NotifyPropertyChanged added specifically to notify of MyCollection re-assignment
        ObservableCollection<MyObject> _MyCollection;
        public ObservableCollection<MyObject> MyCollection
        {
            get { return _MyCollection; }
            set
            {
                if (value != _MyCollection)
                {
                    _MyCollection = value;
                    NotifyPropertyChanged("MyCollection");
                }
            }
        }

        public CollectionViewSource MyCollectionViewSource { get; private set; }
        public ICollectionView MyCollectionView { get; private set; }

        // Method updates MyCollection itself (Called via ICommand from another viewmodel)
        public void UpdateCollection(ObservableCollection<MyObject> NewCollection)
        {
            MyCollection = NewCollection;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,new PropertyChangedEventArgs(info));
            }
        }
    }

    class MyObject
    {
        public string TestString { get; set; }
    }
}

谢谢,

解决方法

我会选择以下两种解决方案之一.

首先,您可以使用ObservableCollection并创建一次ICollectionView(分组,排序).您可以使用.Clear()并添加新Collection中的项目,而不是替换ObservableCollection.这还有一个额外的好处,就是不会破坏你的分组和排序.

第二种方法:无论何时替换ObservableCollection,都必须创建一个新的ICollectionView进行排序和分组.

this._view = (ICollectionView)CollectionViewSource.Getdefaultview(this.MyCollection);

如果使用defaultview,只需绑定到您的集合即可

<DataGrid Name="grid" ItemsSource="{Binding MyCollection}" />

你可以扔掉你的CollectionViewSource代码绑定的东西.

我们今天的关于在WPF中,您是否可以过滤CollectionViewSource而无需编写代码?的分享就到这里,谢谢您的阅读,如果想了解更多关于.net – windows metro app中的CollectionViewSource、c# – WPF将已过滤的ObservableCollection ICollectionView绑定到Combobox、c# – 可观察的CollectionViewSource、c# – 在MVVM世界中更改CollectionViewSource Source的相关信息,可以在本站进行搜索。

本文标签: