Проблема со строками DataGrid в WPF - PullRequest
0 голосов
/ 01 июля 2011

У меня есть таблица данных, в которой у меня есть две кнопки в каждой строке - одна для перемещения строки вверх и одна для перемещения строки вниз.

Каждая кнопка имеет команду, позволяющую пользователю перемещать выбранную строкув любом направлении.Проблема, с которой я сталкиваюсь, заключается в том, что она не работает.Я думаю, что проблема, с которой я могу столкнуться, состоит в том, что другие элементы управления (поля со списком) в строках связаны с источниками данных через модель MVVM, где я манипулирую строками в коде за XAML, думая, что это было бы логичным местомчто делать это.

Код, который я имею для одной из кнопок ниже:

private void MoveRowDown(object sender, ExecutedRoutedEventArgs e)
        {

            int currentRowIndex = dg1.ItemContainerGenerator.IndexFromContainer(dg1.ItemContainerGenerator.ContainerFromItem(dg1.SelectedItem));

            if (currentRowIndex >= 0)
            {
                this.GetRow(currentRowIndex + 1).IsSelected = true;
            }


        }
private DataGridRow GetRow(int index)
        {
            DataGridRow row = (DataGridRow)dg1.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null)
            {
                dg1.UpdateLayout();
                dg1.ScrollIntoView(selectedAttributes.Items[index]);
                row = (DataGridRow)dg1.ItemContainerGenerator.ContainerFromIndex(index);
            }
            return row;
        }

1 Ответ

0 голосов
/ 01 июля 2011

Вы должны манипулировать 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>  

Надеюсь, это поможет!

...