分组后,我在WPF数据网格中遇到一个奇怪的问题。组内的行开始重新排序。我正在使用.code 3.5框架的codeplex中的datagrid。
问题已在msdn论坛中提出。请在下面找到链接。
http://social.msdn.microsoft.com/Forums/en/wpf/thread/3f915bf9-2571-43e8-8560-3def1d0d65bb
msdn用户在帖子的末尾说可能没有解决方法。但我非常需要一个!!
答案 0 :(得分:2)
您是否尝试过通过CustomSort进行排序?我看到这张贴在某处,它对我有用。它需要一点点发现,但它可以通过ListCollectionView
类获得。如下所示:
ListCollectionView lcv =
(ListCollectionView)CollectionViewSource.GetDefaultView(YourObjectCollection);
lcv.CustomSort = new YourObjectComparer();
其中YourObjectComparer
实现IComparer
并对您想要的属性进行排序。
答案 1 :(得分:1)
修改强>
为此,在进行单元格编辑时,我们会删除组并再次添加它们。这会使细胞保持其预期的顺序。但这带来了另一个问题,即所有扩展器都崩溃了。因此,如果我们记住在重新组合后哪个扩展器仍然扩展,我们就能实现您的目标。
有一些事件可以帮助您实现此功能...
DataGrid.CellEditEnding
活动Expander.Initialized
,Expander.Expanded
和Expander.Collpased
次事件ICollectionView.CurrentChanging
活动您需要记住的是展开器展开或折叠时的状态。每个展开器代表由Name
属性表示的分组值。这些分组值是唯一的。因此,Dictionary.Key
为Name
值且Dictionary.Value
为Expander.IsExpanded
标志的字典就足够了。
使用此原材料以下代码可以满足您的需求......
模型类: 我在DataGrid中表示一个简单的Key-Value对象列表。
public class MyKeyValuePair<TKey, TValue> : INotifyPropertyChanged
{
private TKey key;
private TValue value;
public MyKeyValuePair(TKey k, TValue v)
{
key = k;
value = v;
}
public TKey Key
{
get { return key; }
set {
key = value;
OnPropertyChanged("Key");
}
}
public TValue Value
{
get { return value; }
set {
this.value = value;
OnPropertyChanged("Value");
}
}
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged
(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
<强> XAML:强>
<tk:DataGrid
ItemsSource="{Binding}"
CellEditEnding="MyDataGrid_CellEditEnding">
<tk:DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander
Initialized="Expander_Initialized"
Expanded="Expander_Expanded"
Collapsed="Expander_Expanded">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Path=Name}" />
<TextBlock Text=" (" />
<TextBlock
Text="{Binding Path=ItemCount}"/>
<TextBlock Text="( " />
<TextBlock Text="Items"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</tk:DataGrid.GroupStyle>
</tk:DataGrid>
Window.cs代码背后:
public partial class Window8 : Window
{
private Dictionary<string, bool> _dict;
public Window8()
{
InitializeComponent();
_dict = new Dictionary<string, bool>();
var list1 = new List<MyKeyValuePair<string, int>>();
var random = new Random();
for (int i = 0; i < 50; i++)
{
list1.Add(new MyKeyValuePair<string, int>(
i.ToString(), random.Next(300) % 3));
}
var colView = new ListCollectionView(list1);
colView.GroupDescriptions.Add(
new PropertyGroupDescription("Value"));
this.DataContext = colView;
}
private void MyDataGrid_CellEditEnding
(object sender, DataGridCellEditEndingEventArgs e)
{
var dg = sender as DataGrid;
var cellInfo = dg.CurrentCell;
var mySource = dg.ItemsSource as ListCollectionView;
var oldDlg
= new CurrentChangingEventHandler((obj, args) => { return; });
var dlg = new CurrentChangingEventHandler(
(obj, args) =>
{
if (cellInfo.Item == mySource.CurrentItem)
{
var grpDescs = mySource.GroupDescriptions;
var oldGrpDescs
= grpDescs.Cast<PropertyGroupDescription>().ToList();
mySource.Dispatcher.BeginInvoke(
new Action(
() =>
{
grpDescs.Clear();
foreach (var grdpDesc in oldGrpDescs)
{
grpDescs.Add(grdpDesc);
}
mySource.CurrentChanging -= oldDlg;
}));
}
});
oldDlg = dlg;
mySource.CurrentChanging -= oldDlg;
mySource.CurrentChanging += oldDlg;
}
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
var exp = sender as Expander;
var dc = exp.DataContext as CollectionViewGroup;
_dict[dc.Name.ToString()] = exp.IsExpanded;
}
private void Expander_Initialized(object sender, EventArgs e)
{
var exp = sender as Expander;
var dc = exp.DataContext as CollectionViewGroup;
if (_dict != null
&& _dict.ContainsKey(dc.Name.ToString())
&& _dict[dc.Name.ToString()])
{
exp.IsExpanded = true;
}
}
}
但有两个权衡。
Name
键可能/可能不会保持唯一。例如。如果您在FirstName
上进行分组,并且按LastName
进行gropup,则假设有员工列表,则会有嵌套扩展器。现在,一些名字分组可能与某些姓氏分组匹配,例如George
。因此,字典将落入一个技巧,将无法正常工作。希望这有帮助。