2

I have a command wired to the event such that it does fire, but what I get in the CommandParameter is the previously selected item, or maybe it's the selected item before the SelectionChanged completes.

Either way, not sure what to change to get the newly selected item from the event.

<i:Interaction.Triggers>
  <i:EventTrigger EventName="SelectionChanged">
    <cmd:EventToCommand 
    Command="{Binding Main.SelectedRecordCommand, Source={StaticResource Locator}}" 
    CommandParameter="{Binding SelectedItem, ElementName=listBillingRecords}" 
    />
   </i:EventTrigger>
</i:Interaction.Triggers>

Thanks

Roger
  • 2,063
  • 4
  • 32
  • 65

2 Answers2

1

Is it worth using a trigger? If whatever your XAML element is for the collection (listbox, grid, etc) is bound to a property exposing a collection on your viewmodel, you can leverage both databinding and the built-in MVVM Light messenger to notify you of a property change with both old and new values in a more MVVM-friendly way. This example isn't necessarily WP7-specific, but I think it would work the same.

For example, this might be the databound collection:

    public const string BillingRecordResultsPropertyName = "BillingRecordResults";
    private ObservableCollection<BillingRecord> _billingRecordResults = null;
    public ObservableCollection<BillingRecord> BillingRecordResults
    {
        get
        {
            return _billingRecordResults;
        }

        set
        {
            if (_billingRecordResults == value)
            {
                return;
            }

            var oldValue = _billingRecordResults;
            _billingRecordResults = value;

            // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
            RaisePropertyChanged(BillingRecordResultsPropertyName, oldValue, value, true);
        }
    }

I like to expose a property on my ViewModel that is a "selected item" of whatever collection I'm exposing. So, to the ViewModel, I would add this property using the MVVMINPC snippet:

    public const string SelectedBillingRecordPropertyName = "SelectedBillingRecord";
    private BillingRecord _selectedBillingRecord = null;
    public BillingRecord SelectedBillingRecord
    {
        get
        {
            return _selectedBillingRecord;
        }

        set
        {
            if (_selectedBillingRecord == value)
            {
                return;
            }

            var oldValue = _selectedBillingRecord;
            _selectedBillingRecord = value;

            // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
            RaisePropertyChanged(SelectedBillingRecordPropertyName, oldValue, value, true);
        }
    }

Now, if you bind the SelectedItem of the XAML element to this exposed property, it will populate when selected in the View via databinding.

But even better, when you leverage the snippet MVVMINPC, you get to choose whether or not to broadcast the results to anyone listening. In this case, we want to know when the SelectedBillingRecord property changes. So, you can have this in the constructor for your ViewModel:

Messenger.Default.Register<PropertyChangedMessage<BillingRecord>>(this, br => SelectedRecordChanged(br.NewValue));

And elsewhere in your ViewModel, whatever action you want to have happen:

    private void SelectedRecordChanged(BillingRecord br)
    {
        //Take some action here
    }

Hope this helps...

Mike L
  • 4,693
  • 5
  • 33
  • 52
  • yes.. nice reply.. totally agree with all you said. I am already using a observable collection and a prop that fires raisepropchanged in my view model. A few issues though. First, is that if I put a two way binding to the SelectedItem, it is null on the first pass, and I get a index out of range. Second there are a lot of ways the selected item, or my object in the view model get updated. In this case, I only want to know when the change happens with the listview it's in, so I am using the relay command. – Roger Apr 01 '11 at 04:06
  • OK, I see why you opted to use a trigger now. – Mike L Apr 01 '11 at 04:54
  • ug... so I have one page, one control that I need to monitor it's change of this object in my model. Otherwise I have to do a bunch of crazy stuff in the method that gets notified of the change. Suggestions? – Roger Apr 01 '11 at 16:46
  • I created a second property on the viewmodel that is only used by the listbox. Now... I can update the other one when it changes. – Roger Apr 01 '11 at 16:51
  • Bound to the selecteditem? I had thought about suggesting a second property, but wasn't sure if that resolved your null item issue on your two way binding. Also, I can never decide if ancillary properties like that (specifically dedicated to exposing something from one XAML element in the view) tarnish the clean distinction between viewmodel and view. Glad you've got something workable! – Mike L Apr 01 '11 at 20:32
0

I have seen the same issue and found that SelectedItem is the correct implementation.

Shayne Boyer
  • 410
  • 3
  • 9