編輯:
對於本當單元格編輯發生,我們刪除組和重新添加他們。這使細胞保持其預定的秩序。但是這帶來了另一個問題,就是所有的擴張者都崩潰了。因此,如果我們記得重新組合後哪些擴展器仍然擴展,我們將實現您所尋求的。
有幾個事件,可以幫助你實現這個功能...
DataGrid.CellEditEnding
事件
Expander.Initialized
,Expander.Expanded
和Expander.Collpased
事件
ICollectionView.CurrentChanging
事件
所有你需要的請記住擴展器擴展或摺疊時的狀態。每個擴展器表示由Name
屬性表示的分組值。這些分組值是唯一的。所以Dictionary.Key
是這個Name
值的字典和Dictionary.Value
是Expander.IsExpanded
標誌就足夠了。
有了這個原料下面的代碼做你追求的是什麼...
模型類:我代表DataGrid中的鍵值對象的簡單列表。
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
。所以字典將陷入詭計,並且不會正常工作。
希望這會有所幫助。
您可以將DataGrid ItemsSource綁定到CollectionViewSource,並使用SortDescription指定您的排序順序,使得項目不會被重新排序。 – whoisthis
@bjoshi - 我也在做同樣的事情,但它是重新排序! – GuruC