Goal
My goal is to simply move the records up or down and show their row number on the left side of the DataGrid.
Problem
When executing either MoveUpCommand or MoveDownCommand, the rows move, but the Row Number does not update.
See example below:
Summary of the GIF
I select the 1st row with the index of 0. I click the Move Down button to set the index +1 for the selected record in the list. But the problem is, there are now 2 rows with the same row number.
Question
Why is the other record not updating? And how would I update it?
What I have tried
I tried 2 different methods of getting the row numbers. My current code below uses a converter, the other method I have tried was using DataGrid_LoadingRow from this answer here: https://stackoverflow.com/a/4662928/12485722
They both have the same output.
Current Code
XAML
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:VM />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding MainList}"
SelectedItem="{Binding SelectedRecord}"
CanUserAddRows="False"
EnableRowVirtualization="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Converter={local:RowToIndexConverter}}" />
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Column="1">
<Button Content="Move Up" Command="{Binding MoveUpCommand}"/>
<Button Content="Mode Down" Command="{Binding MoveDownCommand}" />
</StackPanel>
</Grid>
</Window>
Model
public class Model
{
public int Id { get; set; }
public string ModelName { get; set; }
}
View Model
public class VM
{
public ObservableCollection<Model> MainList { get; set; } = new ObservableCollection<Model>();
public Model SelectedRecord { get; set; }
public VM()
{
LoadData();
MoveUpCommand = new RelayCommand(MoveUp);
MoveDownCommand = new RelayCommand(MoveDown);
}
private void LoadData()
{
for (int i = 0; i < 50; i++)
{
MainList.Add(new Model { Id = i, ModelName = $"Model Version {i}" });
}
}
public ICommand MoveUpCommand { get; }
private void MoveUp(object param)
{
if (SelectedRecord != null)
{
int currentIndex = MainList.IndexOf(SelectedRecord);
if (currentIndex > 0)
MainList.Move(currentIndex, currentIndex - 1);
}
}
public ICommand MoveDownCommand { get; }
private void MoveDown(object param)
{
if (SelectedRecord != null)
{
int currentIndex = MainList.IndexOf(SelectedRecord);
if (currentIndex != -1 && currentIndex < MainList.Count - 1)
MainList.Move(currentIndex, currentIndex + 1);
}
}
}
Converter
public class RowToIndexConverter : MarkupExtension, IValueConverter
{
static RowToIndexConverter converter;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DataGridRow row = value as DataGridRow;
if (row != null)
return row.GetIndex();
else
return -1;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (converter == null) converter = new RowToIndexConverter();
return converter;
}
public RowToIndexConverter()
{
}
}
