Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ICollectionView对ObservableCollection进行排序不';我不能正常工作_C#_Wpf_Observablecollection_Collectionviewsource_Icollectionview - Fatal编程技术网

C# 使用ICollectionView对ObservableCollection进行排序不';我不能正常工作

C# 使用ICollectionView对ObservableCollection进行排序不';我不能正常工作,c#,wpf,observablecollection,collectionviewsource,icollectionview,C#,Wpf,Observablecollection,Collectionviewsource,Icollectionview,要生成错误,请选择TopDataGrid中的任何项目。因此,项目集合将加载到BottomDataGrid。此集合按我指定的Name属性排序!然后选择TopDataGrid中的任何其他项目。结果是将重新加载BottomDataGrid的ItemsSource。现在收集的是未分类的!集合看起来与我在代码中指定的一样。此外,如果我用调试器检查\u customerView,我会看到排序后的集合 我知道我可以使用List和OrderBy和INotifyPropertyChanged来显式地命令UI更新自

要生成错误,请选择
TopDataGrid
中的任何项目。因此,项目集合将加载到
BottomDataGrid
。此集合按我指定的
Name
属性排序!然后选择
TopDataGrid
中的任何其他项目。结果是将重新加载
BottomDataGrid
ItemsSource
。现在收集的是未分类的!集合看起来与我在代码中指定的一样。此外,如果我用调试器检查
\u customerView
,我会看到排序后的集合

我知道我可以使用
List
OrderBy
INotifyPropertyChanged
来显式地命令UI更新自身,而不是
observeCollection
icCollectionView
。但我认为这不是正确的方法

赢取7.Net 4.0。复制粘贴即可


代码

公共类TopGridItem
{
私人可观测采集(u采集);;
公开收集
{
获取{return\u collection;}
}
公共字符串名称{get;set;}
公共ICollectionView MyCollectionView
{
得到
{
ICollectionView\u customerView=CollectionViewSource.GetDefaultView(集合);
_添加(新的SortDescription(“名称”,ListSortDirection.升序));
return\u customerView;
}
}
公共TopGridItem()
{
_集合=新的ObservableCollection();
_添加(新的BottomGridItem{Name=“bbbbbb”});
_添加(新的BottomGridItem{Name=“aaaaaa”});
_添加(新的BottomGridItem{Name=“aaaaaa”});
_添加(新的BottomGridItem{Name=“ccccc”});
_Add(新的BottomGridItem{Name=“dddddd”});
}
}
公共类项目
{
公共字符串名称{get;set;}
公共字符串索引{get;set;}
}
/// 
///新窗口.xaml
/// 
公共部分类进度窗口:INotifyPropertyChanged
{
公共TopGridItem _selectedItem;
公共字符串名称1{get;set;}
公共字符串索引{get;set;}
公共ObservableCollection项{get;set;}
公共TopGridItem SelectedItem
{
获取{return\u selectedItem;}
设置
{
_选择editem=值;
OnPropertyChanged(“SelectedItem”);
}
}
公共窗口()
{
初始化组件();
DataContext=this;
Items=新的ObservableCollection();
添加(新的TopGridItem{Name=“One”});
添加(新的TopGridItem{Name=“Two”});
添加(新的TopGridItem{Name=“Three”});
}
#区域inotifyproperty已更改
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(handler!=null)handler(这是新的PropertyChangedEventArgs(propertyName));
}
#端区
}
更新

private void ClearSortDescriptionsOnItemsSourceChange()
    {
      this.Items.SortDescriptions.Clear();
      this._sortingStarted = false;
      List<int> descriptionIndices = this.GroupingSortDescriptionIndices;
      if (descriptionIndices != null)
        descriptionIndices.Clear();
      foreach (DataGridColumn dataGridColumn in (Collection<DataGridColumn>) this.Columns)
        dataGridColumn.SortDirection = new ListSortDirection?();
    }

    private static object OnCoerceItemsSourceProperty(DependencyObject d, object baseValue)
    {
      DataGrid dataGrid = (DataGrid) d;
      if (baseValue != dataGrid._cachedItemsSource && dataGrid._cachedItemsSource != null)
        dataGrid.ClearSortDescriptionsOnItemsSourceChange();
      return baseValue;
    }
private void clearsortdescriptionsonimsourcechange()
{
this.Items.SortDescriptions.Clear();
这是。_sortingStarted=false;
List descriptionIndices=this.GroupingSortDescriptionIndices;
if(descriptionIndicates!=null)
descriptionIndicates.Clear();
foreach(DataGridColumn(集合)this.Columns中的DataGridColumn)
dataGridColumn.SortDirection=新列表SortDirection?();
}
私有静态对象OnCorceItemsSourceProperty(DependencyObject d,object baseValue)
{
DataGrid DataGrid=(DataGrid)d;
if(baseValue!=dataGrid.\u CachedItemSource&&dataGrid.\u CachedItemSource!=null)
dataGrid.ClearSortDescriptionSonimSourceChange();
返回基值;
}

似乎在
clearsortdescriptionsonemsourcechange
中,方法排序被清除,不再重新指定。我认为这就是问题所在。

有一个棘手的解决办法:O)

更改
TopGridItem
类,使其实现
INotifyPropertyChanged
,然后更改
MyCollectionView
属性,如下所示:

public ICollectionView MyCollectionView
{
    get
    {
        return _myCollectionView;
    }
    set
    {
        _myCollectionView = value;
        OnPropertyChanged("MyCollectionView");
    }
}
ICollectionView _myCollectionView;
TopGridItem
添加公共方法,如下所示:

public void ResetView()
{
    MyCollectionView = null;  // This is the key to making it work
    ICollectionView customerView = CollectionViewSource.GetDefaultView(_collection);
    customerView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
    MyCollectionView = customerView;
}
这要求将
\u collection
设置为类字段,而不是仅在构造函数中使用的变量。说到这里:

public TopGridItem()
{
    _collection = new ObservableCollection<BottomGridItem>();
    _collection.Add(new BottomGridItem { Name = "bbbbbb" });
    _collection.Add(new BottomGridItem { Name = "aaaaa" });
    _collection.Add(new BottomGridItem { Name = "aaaaa" });
    _collection.Add(new BottomGridItem { Name = "ccccc" });
    _collection.Add(new BottomGridItem { Name = "dddddd" });

    ResetView();
}
我已经在这里测试过了,它似乎有效。如果没有,那么我一定是在某个地方打错了字,或者我发布的代码中遗漏了什么


代码的工作版本 XAML:

<Window x:Class="WpfApplication4.MainWindow"
        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>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Items}"
                  SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  CanUserResizeRows="False"
                  CanUserSortColumns="False"
                  SelectionMode="Single"
                  SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

        <DataGrid Grid.Row="1"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding SelectedItem.MyCollectionView}"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  CanUserResizeRows="False"
                  CanUserSortColumns="False"
                  SelectionMode="Single"
                  SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}"></DataGridTextColumn>
                <DataGridTextColumn Binding="{Binding Index}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0"
                     Text="{Binding Name1}"></TextBox>
            <TextBox Grid.Column="1"
                     Text="{Binding Index}"></TextBox>
        </Grid>
    </Grid>
</Window>

代码隐藏:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication4
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Items = new ObservableCollection<TopGridItem>();
            Items.Add(new TopGridItem { Name = "One" });
            Items.Add(new TopGridItem { Name = "Two" });
            Items.Add(new TopGridItem { Name = "Three" });
        }

        public String Name1 { get; set; }
        public String Index { get; set; }
        public ObservableCollection<TopGridItem> Items { get; private set; }

        public TopGridItem SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                OnPropertyChanged("SelectedItem");
                if (_selectedItem != null)
                {
                    _selectedItem.ResetView();
                }
            }
        }
        TopGridItem _selectedItem;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class TopGridItem : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public String Name { get; set; }

        public ICollectionView MyCollectionView
        {
            get
            {
                return _myCollectionView;
            }
            set
            {
                _myCollectionView = value;
                OnPropertyChanged("MyCollectionView");
            }
        }
        ICollectionView _myCollectionView;

        public void ResetView()
        {
            MyCollectionView = null;
            ICollectionView _customerView = CollectionViewSource.GetDefaultView(_collection);
            _customerView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            MyCollectionView = _customerView;
        }

        ObservableCollection<BottomGridItem> _collection;

        public TopGridItem()
        {
            _collection = new ObservableCollection<BottomGridItem>();
            _collection.Add(new BottomGridItem { Name = "bbbbbb" });
            _collection.Add(new BottomGridItem { Name = "aaaaa" });
            _collection.Add(new BottomGridItem { Name = "aaaaa" });
            _collection.Add(new BottomGridItem { Name = "ccccc" });
            _collection.Add(new BottomGridItem { Name = "dddddd" });
            ResetView();
        }
    }

    public class BottomGridItem
    {
        public String Name { get; set; }
        public String Index { get; set; }
    }
}
使用系统;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
使用System.Windows.Data;
命名空间WpfApplication4
{
公共部分类主窗口:窗口,INotifyPropertyChanged
{
公共主窗口()
{
初始化组件();
DataContext=this;
Items=新的ObservableCollection();
添加(新的TopGridItem{Name=“One”});
添加(新的TopGridItem{Name=“Two”});
添加(新的TopGridItem{Name=“Three”});
}
公共字符串名称1{get;set;}
聚氨基甲酸酯
<Window x:Class="WpfApplication4.MainWindow"
        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>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Items}"
                  SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  CanUserResizeRows="False"
                  CanUserSortColumns="False"
                  SelectionMode="Single"
                  SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

        <DataGrid Grid.Row="1"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding SelectedItem.MyCollectionView}"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  CanUserResizeRows="False"
                  CanUserSortColumns="False"
                  SelectionMode="Single"
                  SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}"></DataGridTextColumn>
                <DataGridTextColumn Binding="{Binding Index}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0"
                     Text="{Binding Name1}"></TextBox>
            <TextBox Grid.Column="1"
                     Text="{Binding Index}"></TextBox>
        </Grid>
    </Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication4
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Items = new ObservableCollection<TopGridItem>();
            Items.Add(new TopGridItem { Name = "One" });
            Items.Add(new TopGridItem { Name = "Two" });
            Items.Add(new TopGridItem { Name = "Three" });
        }

        public String Name1 { get; set; }
        public String Index { get; set; }
        public ObservableCollection<TopGridItem> Items { get; private set; }

        public TopGridItem SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                OnPropertyChanged("SelectedItem");
                if (_selectedItem != null)
                {
                    _selectedItem.ResetView();
                }
            }
        }
        TopGridItem _selectedItem;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class TopGridItem : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public String Name { get; set; }

        public ICollectionView MyCollectionView
        {
            get
            {
                return _myCollectionView;
            }
            set
            {
                _myCollectionView = value;
                OnPropertyChanged("MyCollectionView");
            }
        }
        ICollectionView _myCollectionView;

        public void ResetView()
        {
            MyCollectionView = null;
            ICollectionView _customerView = CollectionViewSource.GetDefaultView(_collection);
            _customerView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            MyCollectionView = _customerView;
        }

        ObservableCollection<BottomGridItem> _collection;

        public TopGridItem()
        {
            _collection = new ObservableCollection<BottomGridItem>();
            _collection.Add(new BottomGridItem { Name = "bbbbbb" });
            _collection.Add(new BottomGridItem { Name = "aaaaa" });
            _collection.Add(new BottomGridItem { Name = "aaaaa" });
            _collection.Add(new BottomGridItem { Name = "ccccc" });
            _collection.Add(new BottomGridItem { Name = "dddddd" });
            ResetView();
        }
    }

    public class BottomGridItem
    {
        public String Name { get; set; }
        public String Index { get; set; }
    }
}
public TopGridItem SelectedItem 
{
    get { return _selectedItem; }

    set
    {
        _selectedItem = value;
        OnPropertyChanged("SelectedItem");

        // _dataGrid - link to BottomDataGrid  
        _dataGrid.Items.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));

    }
}
public TopGridItem SelectedItem 
{
    get { return _selectedItem; }

    set
    {
        _selectedItem = value;
        OnPropertyChanged("SelectedItem");

        if (_selectedItem != null)
        _selectedItem.MyCollectionView.Refresh();
    }
}