+2  A: 

I usually expose a CollectionView from the view model and set the IsSynchronizedWithCurrentItem property on the ItemsControl displaying the list in the view. Then when the command is executed, I can inspect the CollectionView.CurrrentItem propety to see what is currently selected.

EDIT: This answer addresses the first question in your, um, question. Rather than your view sending the currently selected item to the ViewModel, the ViewModel keeps track of the currently selected item. So using this technique you don't need to work out how to send that information.

Something like this in your view model:

class ApplicationViewModel
{
    // Exposes a list of ShipmentViewModels.
    public CollectionView Shipments { get; private set; }

    // A DelegateCommand or similar, that when executed calls AddPallet().
    public ICommand AddPalletCommand { get; private set; }

    void AddPallet()
    {
        ShipmentViewModel shipment = (ShipmentViewModel)Shipments.CurrentItem;
        shipment.Pallets.Add(new PalletViewModel(...));
    }
}

And then this in your xaml:

<ListBox ItemsSource="{Binding Shipments}" IsSynchronizedWithCurrentItem="True"/>
<Button Command="{Binding AddPalletCommand}>Add Pallet</Button>

This way you can also track the selection of the Shipments collection from your ViewModel and update the command's CanExecute state.

Does that help any?

Groky
Is there a way to do this with an Observable collection? I Already have invested a large amount of effort into getting things to work with an Observable collection. But if you believe this is a more advisable route, perhaps I'll look into it. What advantages does a collection view have over a observable collection?
Narcolapser
No, but you should just be able to replace your ObservableCollection with a CollectionView. Or in many cases I expose both: Shipments and ShipmentsView where Shipments is an ObservableCollection and ShipmentsView is a CollectionView. You will often want different views on a collection anyway.
Groky
CollectionViews also give you filtering and sorting. In fact, your ItemsCollections is automatically creating one in the background each time you bind to an ObservableCollection anyway. There's an informative article on them here: http://www.drwpf.com/blog/Home/tabid/36/EntryID/18/Default.aspx
Groky
Ok, I'm liking this. I'm always for cutting out a middle man when ever possible. I'm working on setting up on a CollectionView now instead of an Observable collection. So far it seems to be working. At least it would seem. I set the ShipmentsList to the CollectionView but i can't figure out how to populate the list. CollectionView does not seem to have an add command? How do i get around that? I'm I supposed to have an observable collection and the collection view just reflects off of that?
Narcolapser
Yes, that's the idea. You create your ObservableCollection the same as before, and then you construct you CollectionView with "new ListCollectionView(sourceCollection)".
Groky
Ok, that works just fine. The only thing I haven't gotten working is sorting... and the making of a new pallet. but my gut tells me that there is probably a very easy way to do sorting. previously i had been doing this in the code behind:ShipmentsList.Items.SortDescriptions.Clear() ShipmentsList.Items.SortDescriptions.Add(New SortDescription("Status", ListSortDirection.Ascending)) Any tips on an easier way?As goes pallets, it in theory should work. I have the list view bound to the Shipments CV, but i don't think selected shipment is changing. what am i missing here?
Narcolapser
Re: sorting, might be best to start a new question there rather than discussing it in the comments! Re: selection not changing, are you sure you're setting IsSynchronizedWithCurrentItem on the view?
Groky
<ListBox x:Name="ShipmentsList" IsSynchronizedWithCurrentItem="True" ItemTemplate="{DynamicResource ShipmentViewModelTemplate}" ItemsSource="{Binding Shipments}"/> I assume so. Is there something else that might be getting in the way? Am I missing a Dynamic Resource somewhere?
Narcolapser
Never mind. got it. i had two details leading me astray: I put a text block on my UI that was bound to the selected shipment GUID, but for some reason it didn't refresh when I changed the selected shipment. I put the guid into a text box that would pop up every time I clicked new pallet, and it was working fine. Thanks! <br/> The other thing is that I don't actually have a list of Pallets in my shipments. xD I have a list of Pallets separately. So I think from here it's just dealing with my own architecture. Thanks Groky!
Narcolapser
A: 

For keeping track of the currently selected item I do something similar to Groky, maybe this example make a little more sense.

In your ViewModel that contains the collection that your list is bound to (I'm using a ListBox in this example) expose a property that relates to the selected item.

// Assuming your using the MVVM template from Microsoft
public class PalletListViewModel : ViewModelBase
{
   // The collection our list is bound to
   private ObservableCollection<Pallet> _palletList;
   // The current selected item
   private Pallet _selectedPallet;
   // Our command bound to the button
   private DelegateCommand _processCommand;

   public ObservableCollection<Pallet> PalletList
   {
      get { return _palletList; }
   }

   public Pallet SelectedPallet
   {
      get { return _selectedPallet; }
      set
      {
         if(value == _selectedPallet)
            return;

         _selectedPallet = value;

         // INotifyPropertyChanged Method for updating the binding
         OnPropertyChanged("SelectedPallet");
      }
   }

   public ICommand ProcessCommand
   {
      get
      {
         if(_processCommand == null)
            _processCommand = new DelegateCommand(Process);
         return _processCommand;
      }
   }

   private void Process()
   {
      // Process the SelectedPallet
   }
}

<Window ...>
   <Grid x:Name="LayoutRoot">
      <Button Content="Process Pallet" Command="{Binding ProcessCommand}" />
      <ListBox ItemsSource="{Binding PalletList}" SelectedItem="{Binding SelectedPallet}">
         ...
      </ListBox>
   </Grid>
</Window>

Hopefully this is what your looking for.

jwarzech
It's helping that's for sure. Anyway, I'm guessing looking at both of your responses that it isn't possible to directly use a command binding to send data to the ViewModel? Tragic. >_<How do you get the listbox to take the selected item binding? I try to enter that in VS and my program reports and error, I try in blend and it just won't let me. Code:<ListBox x:Name="ShipmentsList" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding SelectedShipment}" ItemTemplate="{DynamicResource ShipmentViewModelTemplate}" ItemsSource="{Binding OpenShipment}"/>
Narcolapser
Just to make sure are you binding your View's DataContext to the ViewModel? (Or if using test data in blend setting the datacontext in your xaml) There is a way to pass arguments to your command if that is what your asking using the CommandParameter attribute. However from what I can gather most people use a bound property to get the SelectedItem.
jwarzech
jwarzech
It is. but I don't believe I am using the VMB from the MVVM toolkit, though I might look into it. Right now I believe we are using a custom built VMB, Though we might switch it it is advisable. This program is kind of our proving grounds application. So details like that are what I want to find out now before we go into the next MUCH MUCH LARGER project. Also We are not using DelegateCommand, we are using RelayCommand. This to can be changed.
Narcolapser
Though at this point the easiest thing to do would probably be the CommandParameter attribute, how do i make use of that?
Narcolapser