РЕДАКТИРОВАНИЕ:
Для этого, когда происходит редактирование ячейки, мы удаляем группы и добавляем их снова.Это заставляет клетку оставаться в заданном порядке.Но это создает еще одну проблему, которая заключается в том, что все расширители рухнули.Поэтому, если мы помним, какие расширители остаются развернутыми после перегруппировки, мы достигаем того, что вы ищете.
Есть несколько событий, которые могут помочь вам в достижении этой функциональности ...
DataGrid.CellEditEnding
событие Expander.Initialized
, Expander.Expanded
и Expander.Collpased
события ICollectionView.CurrentChanging
событие
Все, что вам нужно запомнитьэто состояние расширителей, когда они развернуты или свернуты.Каждый расширитель представляет сгруппированное значение, представленное свойством Name
.Эти сгруппированные значения являются уникальными.Поэтому достаточно словаря, в котором Dictionary.Key
- это значение Name
, а Dictionary.Value
- флаг Expander.IsExpanded
.
С этим raw * следующий код выполняет то, что вы ищете...
Класс модели: Я представляю простой список объектов Key-Value в 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
вложенные расширители.Теперь некоторая группировка имен может совпадать с некоторой группировкой фамилий, например George
.Таким образом, словарь впадет в уловку и не будет работать правильно.
Надеюсь, это поможет.