In my WPF app I have a datagrid like
<DataGrid
SelectedItem="{Binding SelItm, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding FilteredStudents}"
SelectionMode="Extended"
AutoGenerateColumns="False"
IsReadOnly="True"
SelectionUnit="FullRow"
HeadersVisibility="Column"
<DataGrid.Columns>
<DataGridTextColumn
Header="Bill No."
Binding="{Binding Path=Name, Mode=OneWay}"
Width="260"
IsReadOnly="True" />
<DataGridTextColumn
Header="Bill Date"
Binding="{Binding Path=Address, Mode=OneWay}"
Width="200"
IsReadOnly="True" />
<DataGridTextColumn
Header="Amount"
Binding="{Binding Path=Age, Mode=OneWay}"
Width="210"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
The itemsource of the datagrid is an ICollectionView
called FilteredStudents
. I've created a property selrows
in my viewmodel which I binded to a label to display the selected rows count using like selrows = SelItm.Count();
.
private ICollectionView _allFilteredStudents;
public ICollectionView FilteredStudents
{
get
{
if(_allFilteredStudents == null)
{
this._allFilteredStudents = new ListCollectionView(GetAllStudents)
{
Filter = o => ((Students)o).Name != "Ram"
};
}
return _allFilteredStudents;
}
}
But it is displaying incorrect result.
BTW, my database looks like
What is the proper way to get the selected rows count of a WPF datagrid following mvvm pattern?
CodePudding user response:
Here is the solution:
If you are going to show the number of the selected row in the view, simply choose a name for the grid and bind to SelectedItems.Count
of the grid.
In order to access selected items count in your c# code, you can add a IsSelected
property to the StudentModel
and bind it to the row's IsSelected
attribute using RowStyle
. This way whenever a row is selected/unselected, the IsSelected
property of the StudentModel
will be updated in the code and you can find selected students using that proertry like this FilteredStudents.Cast<StudentModel>().Count(i => i.IsSelected)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="GetSelectedRowsCount" Command="{Binding ButtonCommand}"/>
<TextBlock Grid.Row="1" Text="{Binding ElementName=grid, Path=SelectedItems.Count}"/>
<DataGrid Grid.Row="2" x:Name="grid"
ItemsSource="{Binding FilteredStudents}"
SelectionMode="Extended"
AutoGenerateColumns="False"
IsReadOnly="True"
SelectionUnit="FullRow"
HeadersVisibility="Column" >
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected" Value="{Binding Path = IsSelected}"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Path=Id, Mode=OneWay}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, Mode=OneWay}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
Now there is a IsSelected
property in your StudentModel
you can find how many rows are selected by filtering the collection in your code.
Here is the student model:
public class StudentModel : Notifier
{
private int _id;
public int Id
{
get { return _id; }
set
{
this._id = value;
RaisePropertyChanged();
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
this._name = value;
RaisePropertyChanged();
}
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
this._isSelected = value;
RaisePropertyChanged();
}
}
}
and this is the viewModel:
public class AppPresenter : Notifier
{
private ICollectionView _allFilteredStudents;
public ICollectionView FilteredStudents
{
get
{
if (_allFilteredStudents == null)
{
this._allFilteredStudents = new ListCollectionView(GetAllStudents())
{
Filter = o => ((StudentModel)o).Name != "Ram"
};
}
return _allFilteredStudents;
}
}
public List<StudentModel> GetAllStudents()
{
return new List<StudentModel>()
{
new StudentModel(){ Id=1, Name="name1"},
new StudentModel(){ Id=2, Name="name2"},
new StudentModel(){ Id=3, Name="name3"},
new StudentModel(){ Id=4, Name="name4"},
};
}
public int GetSelectedRowCount()
{
var selrows = FilteredStudents.Cast<StudentModel>().Count(i => i.IsSelected);
return selrows;
}
private RelayCommand _buttonCommand;
public RelayCommand ButtonCommand
{
get
{
if (_buttonCommand == null)
{
_buttonCommand = new RelayCommand(param => this.GetSelectedRowCount());
}
return _buttonCommand;
}
}
}
Finally this is the MainWindow.cs
public MainWindow()
{
InitializeComponent();
this.DataContext = new AppPresenter();
}