Roger
Roger

Reputation: 2135

Correct way to use a Interaction Trigger on SelectionChanged Event

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

Upvotes: 2

Views: 1445

Answers (2)

Shayne Boyer
Shayne Boyer

Reputation: 410

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

Upvotes: 0

Mike L
Mike L

Reputation: 4913

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...

Upvotes: 1

Related Questions