SEE MY ANSWER AT THE BOTTOM
Just doing some light reading on WPF where I need to bind the selectedItems from a DataGrid but I am unable to come up with anything tangible. I just need the selected objects.
DataGrid:
<DataGrid Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="4"
Name="ui_dtgAgreementDocuments"
ItemsSource="{Binding Path=Documents, Mode=TwoWay}"
SelectedItem="{Binding Path=DocumentSelection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White"
SelectionMode="Extended" Margin="2,5"
IsReadOnly="True"
CanUserAddRows="False"
CanUserReorderColumns="False"
CanUserResizeRows="False"
GridLinesVisibility="None"
HorizontalScrollBarVisibility="Hidden"
columnHeaderStyle="{StaticResource GreenTea}"
HeadersVisibility="Column"
BorderThickness="2"
BorderBrush="LightGray"
CellStyle="{StaticResource NonSelectableDataGridCellStyle}"
SelectionUnit="FullRow"
HorizontalContentAlignment="Stretch" AutoGenerateColumns="False">
With a bit of trickery you can extend the DataGrid to create a bindable version of the
SelectedItems
property. My solution requires the binding to haveMode=OneWayToSource
since I only want to read from the property anyway, but it might be possible to extend my solution to allow the property to be read-write.I assume a similar technique could be used for ListBox, but I haven't tried it.
I came here for the answer and I got a lot of great ones. I combined them all into an attached property, very similar to the one offered by Omar above, but in one class. Handles INotifyCollectionChanged and switching the list out. Doesn't leak events. I wrote it so it would be pretty simple code to follow. Written in C#, handles listbox selectedItems and dataGrid selectedItems.
This works on both DataGrid and ListBox.
(I just learned how to use GitHub) GitHub https://github.com/ParrhesiaJoe/SelectedItemsAttachedWpf
To Use:
And here's the code. There is a little sample on Git.
I can assure you: SelectedItems is indeed bindable as a XAML CommandParameter
After a lot of digging and googling, I have finally found a simple solution to this common issue.
To make it work you must follow ALL the following rules:
Following Ed Ball's suggestion', on you XAML command databinding, define CommandParameter property BEFORE Command property. This a very time-consuming bug.
Make sure your ICommand's CanExecute and Execute methods have a parameter of object type. This way you can prevent silenced cast exceptions that occurs whenever databinding CommandParameter type does not match your command method's parameter type.
private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)
{
}
private bool OnDeleteSelectedItemsExecute(object SelectedItems)
{
}
For example, you can either send a listview/listbox's SelectedItems property to you ICommand methods or the listview/listbox it self. Great, isn't it?
Hope it prevents someone spending the huge amount of time I did to figure out how to receive SelectedItems as CanExecute parameter.
The solution mentioned by devuxer
does not work when having large dataset. You will need to disable row virtualization, and that is exactly the case where you need it...
EnableRowVirtualization="False"
I know this post is a little old and has been answered. But I came up with a non MVVM answer. Its easy and works for me. Add another DataGrid, assuming your Selected Collection is SelectedResults:
And in code behind, add this to the Constructor:
I had a solution for this using a workaround that fited my needs.
Make an event to command on the listitemtemplate on MouseUp and as a commandParameter send the SelectedItems collection
That way you can have a command in the viewmodel that handles this or saves the selected items for later use. Have fun coding