【发布时间】:2015-01-29 13:00:10
【问题描述】:
要生成错误,请选择TopDataGrid 中的任何项目。结果,项目集合将被加载到BottomDataGrid。这个集合按我指定的Name 属性排序!然后选择TopDataGrid 中的任何其他项目。结果是 ItemsSource 的 BottomDataGrid 将被重新加载。现在这个集合是未分类的!该集合看起来就像我在代码中指定的那样。此外,如果我使用调试器检查_customerView,我会看到排序后的集合。
我知道我可以使用 List 与 OrderBy 和 INotifyPropertyChanged 来明确命令 UI 更新自身,而不是 ObservableCollection 和 ICollectionView。但我认为这不是正确的方法。
Win 7、.Net 4.0。只需复制和粘贴即可。
<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>
代码
public class TopGridItem
{
private ObservableCollection<BottomGridItem> _collection;
public ObservableCollection<BottomGridItem> Collection
{
get { return _collection; }
}
public String Name { get; set; }
public ICollectionView MyCollectionView
{
get
{
ICollectionView _customerView = CollectionViewSource.GetDefaultView(Collection);
_customerView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
return _customerView;
}
}
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" });
}
}
public class BottomGridItem
{
public String Name { get; set; }
public String Index { get; set; }
}
/// <summary>
/// Логика взаимодействия для NewWindow.xaml
/// </summary>
public partial class ProgressWindow : INotifyPropertyChanged
{
public TopGridItem _selectedItem;
public String Name1 { get; set; }
public String Index { get; set; }
public ObservableCollection<TopGridItem> Items { get; set; }
public TopGridItem SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public ProgressWindow()
{
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"});
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
更新
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;
}
似乎在ClearSortDescriptionsOnItemsSourceChange 方法中排序被清除并且不再重新指定。我想这就是问题所在。
【问题讨论】:
-
因为您只在
_collection构造函数(使用SortDescriptions)中创建_collection一次创建ListCollectionView的实例(使用SortDescriptions)并始终在MyCollectionView中返回它 -
@dkozl 不起作用。都一样
-
当用户点击最上面的网格项时,你想让_collection列表排序还是取消排序?
-
@SwDevMan81 显然已排序。现在没有排序
-
@monstr 这似乎是
DataGrid控件的某种问题。如果数据网格被切换为ListBox之类的东西,我将无法复制该问题。我不知道为什么会这样。你确定要使用DataGrid作为底部控件吗?
标签: c# wpf observablecollection collectionviewsource icollectionview