0
votes

I have the following DataGrid in WPF :

<DataGrid x:Name="dgPatientMedicationOrderList" Width="Auto" HorizontalAlignment="Stretch" RowHeight="40" Background="Transparent" HorizontalContentAlignment="Left" 
                      GridLinesVisibility="None" RowHeaderWidth="0" VirtualizingStackPanel.VirtualizationMode="Standard" SelectedIndex="-1" 
                      ScrollViewer.HorizontalScrollBarVisibility="Disabled" AutoGenerateColumns="False" SelectionMode="Single"
                      IsSynchronizedWithCurrentItem="True" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Stretch" IsReadOnly="True"
                      ItemsSource="{Binding PatientOrdersCollectionView}">

When a user clicks on a row in the DataGrid, it's SelectionChanged event is fired and the bound ViewModel command drives the View to load another user control corresponding to the DG row. In my view I am changing my datagrid's source binding from my ViewModel. Now the problem is that every time the ItemsSource is changed the SelectionChanged event is fired selecting the first item in the DataGrid; this is followed by the view loading the user control without the user explicitly selecting the DataGrid row. How can I prevent the DataGrid from selecting any Row when it's ItemsSource is changed ?

Simplified Demo Code:

XAML:

    <Button Content="Change Source" Command="{Binding ChangeItemsSourceCmd}" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,20" />
    <StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Left" Orientation="Vertical">
        <TextBlock Text="{Binding SelectedPerson.Id, StringFormat=ID: {0}}" />
        <TextBlock Text="{Binding SelectedPerson.Name, StringFormat=Name: {0}}" />
        <TextBlock Text="{Binding SelectedPerson.Gender, StringFormat=Gender: {0}}" />
        <TextBlock Text="{Binding SelectedPerson.Country, StringFormat=Country: {0}}" />
    </StackPanel>
</Grid>

ViewModel:

public class WindowViewModel : ViewModelBase
{
    private Person _selectedPerson;
    private ObservableCollection<Person> _personList;

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set { RaisePropertyChange<Person>(() => SelectedPerson, ref _selectedPerson, ref value); }
    }
    public ObservableCollection<Person> PersonList
    {
        get { return _personList; }
        set
        {
            SelectedPerson = null;
            RaisePropertyChange<ObservableCollection<Person>>(() => PersonList, ref _personList, ref value);
        }
    }

    public WindowViewModel()
    {
        PersonList = new ObservableCollection<Person>()
        {
            new Person() { Id=101, Name="Mahesh", Gender="Male", Country="India"},
            new Person() { Id=102, Name="Srinivas", Gender="Male", Country="Sri Lanka"},
            new Person() { Id=103, Name="Isha", Gender="Female", Country="United States"},
            new Person() { Id=104, Name="Salim", Gender="Male", Country="Pakistan"}
        };
    }

    public ICommand ChangeItemsSourceCmd
    {
        get
        {
            return new RelayCommand(ChangeItemsSourceCmdHandler);
        }
    }

    private void ChangeItemsSourceCmdHandler()
    {
        PersonList = new ObservableCollection<Person>()
        {
            new Person() { Id=105, Name="Raman", Gender="Male", Country="Uganda"},
            new Person() { Id=106, Name="Anurag", Gender="Male", Country="England"},
            new Person() { Id=107, Name="Komal", Gender="Female", Country="Thailand"},
            new Person() { Id=108, Name="Nitin", Gender="Male", Country="Africa"}
        };
    }
}
1
before ItemsSource is changed, make ItemsSource =null, and then change itRang
1. Change the ItemsSource. 2. Set the DataGrid.SelectedItem to null.Sheridan

1 Answers

0
votes

You should:

1.Add a SelectedItem Binding in your DataGrid:

SelectedItem="{Binding Selected, Mode=TwoWay}"

2.Have the related property (firing PropertyChanged of course)

public object Selected
{
  get { return selected; }
  set
  {
    selected = value;
    OnPropertyChanged("Selected");
  }
}

3.Set it to null in your Itemssource setter (or before you change it)

public IEnumerable PatientOrdersCollectionView
{
  get { return patientOrdersCollectionView; }
  set
  {
    Selected = null; // Put it to null here to unselect it from grid
    patientOrdersCollectionView = value;
    OnPropertyChanged("PatientOrdersCollectionView");
  }
}

Should do the trick.