Вы должны манипулировать CollectionView
для DataGrid. CollectionView отвечает за то, как ваши данные выглядят в основном. Вот небольшой пример:
Предположим, вы связали свой DataGrid
с ObservableCollection<T>
с именем Items , и у этого T
есть свойство с именем Index , по которому производится сортировка.
Инициализируйте ICollectionView
в вашей ViewModel следующим образом:
private ICollectionView cvs;
ctor(){
/*your default init stuff*/
/*....*/
cvs = CollectionViewSource.GetDefaultView(items);
view.SortDescriptions.Add(new SortDescription("Index",ListSortDirection.Ascending));
}
Теперь вы можете привязать команду кнопки к команде Up (также в вашей ViewModel):
private ICommand upCommand;
public ICommand Up
{
get { return upCommand ?? (upCommand = new RelayCommand(p => MoveUp())); }
}
private void MoveUp()
{
var current = (Item)view.CurrentItem;
var i = current.Index;
var prev = Items.Single(t => t.Index == (i - 1));
current.Index = i - 1;
prev.Index = i;
view.Refresh(); //you need to refresh the CollectionView to show the changes.
}
ПРЕДУПРЕЖДЕНИЕ: вы должны добавить проверки, чтобы увидеть, есть ли предыдущий элемент и т. Д. В качестве альтернативы вы можете указать делегат CanExecute, который проверяет индекс элемента и включает / отключает кнопку.
(RelayCommand
любезно предоставлено Джошем Смитом / Карлом Шиффлеттом, больше не могу найти правильную ссылку)
Привязать команду к кнопке следующим образом (при условии, что вашей view-моделью является DataContext вашего окна):
<DataGridTemplateColumn >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Up"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},
Path=DataContext.Up}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Надеюсь, это поможет!