6

I have a issue when trigger comes in ViewModel the SelectedItem(parameter) comes the previously selected Item. I need the newly selected item as parameter on selectionChanged.

I am new in WP8. Below is the code

    <toolkit:ListPicker Header="Background"
                                    ExpansionMode="FullscreenOnly"
                                    Template="{StaticResource ListPickerControlTemplate}"
                                    VerticalAlignment="Top"
                                    ItemsSource="{Binding Path=Buildings.ObjectList}"
                                    Margin="0"
                                    x:Name="buldings"
                                    Padding="0">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectionChanged">
                            <i:InvokeCommandAction  Command="{Binding Path=BuildingSelectionCommand}"
                                                    CommandParameter="{Binding Path=SelectedItem, ElementName=buldings}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>

Thanks Vinod

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
vinod8812
  • 645
  • 10
  • 27

3 Answers3

2

Normally should you get the currently SelectionItem passed as parameter to your Command. Since the event is written in past tense, so that you should get the currently SelectedItem and not the previously one.

What you can try is to add a binding for the SelectedItem to your ListPicker and omit passing the SelectedItem to your Command as parameter.

<toolkit:ListPicker SelectedItem="{Binding SelectedBuilding, Mode=TwoWay}" >
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction  Command="{Binding Path=BuildingSelectionCommand}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</toolkit:ListPicker>

Your command then needs to access the property SelectedBuilding to execute

  public class BuildingSelectionCommand{

      // a reference to your ViewModel that contains the SelectedBuilding-Property
      public BuildingsViewModel ViewModel {
         get;
         set;
      }

      public bool CanExecute(object parameter) {
         return ViewModel.SelectedBuilding != null;
      }

      public void Execute(object parameter){
         var selectedItem = ViewModel.SelectedBuilding;

         // execute command logic with selectedItem
      }
  }

The code can be diffrent on your side, cause it depends on how you have implemented your ViewModel and Command, but i think you should get it.

Another way without using an EventTrigger, is to execute the command directly in your SelectedBuilding-Property.

public Building SelectBuilding{
     get {
       return _selectedBuilding
     }
     set{
       _selectedBuilding = value;
       RaisePropertyChanged("SelectedBuilding");

       if (BuildingSelectionCommand.CanExecute(_selectedBuilding)) {
         BuildingSelectionCommand.Execute(_selectedBuilding);
       }
     }
Jehof
  • 34,674
  • 10
  • 123
  • 155
  • I didn't find SelectedItemChanged as event of ListPicker. And I tried above code and it didn't work. Its not getting fired. – vinod8812 May 02 '13 at 06:18
  • @vinod8812 correct, the ListPicker has only the SelectionChanged-Event. its my fault. i´ve updated my answer to provide another solution – Jehof May 02 '13 at 06:47
  • I don't think this will work as I want to execute an async method. Neither way I can execute an async method. – vinod8812 May 02 '13 at 08:19
  • @vinod8812 what do you mean by async method. I think you should add more details to your question – Jehof May 02 '13 at 08:26
  • Async method doesn't run on UI thread which make UI responsive even if you do heavy operation like calling web method etc. That is why in c# 4.5 we use this method for windows 8/phone. – vinod8812 May 02 '13 at 09:11
  • @vinod8812 yeah ok, but i don´t know what the async method has to do with the problem you describe in your question. – Jehof May 02 '13 at 09:13
  • you know what the exact issue is. I can't use propertyChanged event so we need to find a way to execute selectionChanged on after selection changed not before – vinod8812 May 02 '13 at 09:28
2

XAML:

<i:EventTrigger EventName="SelectionChanged">
    <command:EventToCommand Command="{Binding BuildingSelectionCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>

Command:

RelayCommand<SelectionChangedEventArgs> BuildingSelectionCommand { get; set; }

BuildingSelectionCommand = new RelayCommand<SelectionChangedEventArgs>(async (args) => { });

You just missed the "PassEventArgsToCommand". Make sure your command has a SelectionChangedEventArgs.

SBoss
  • 8,845
  • 7
  • 28
  • 44
1

The simple way to solve it is to use

SelectedItem="{Binding SelectedBuilding, Mode=TwoWay}"

as Jehof suggested and get rid of all the "<i:" trigger settings but simply handle the change in the SelectedBuilding property setter and call a method instead of using commands to wrap a method call. You are not gaining anything with a command since you are not even using CanExecute here, but simply adding more code.

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
  • dude I can't use property changed event to call heavy methods that too async methods – vinod8812 May 03 '13 at 04:54
  • @vinod8812 I really don´t know what your problem is, you get 2 answer now and you always talk about your async methods. Your question is about, that you always get the wrong item passed as parameter to your command. You should update your question to provide more information or you should answer another question – Jehof May 03 '13 at 07:03
  • You don't use PropertyChanged here. I think you have a misunderstanding of what async methods are. You can call an async method from SelectedBuilding setter and that's it. – Filip Skakun May 03 '13 at 14:42
  • I don't like this approach. If your app is resuming, the setters will be hit to restore the state. That means you're potentially running code you only actually wanted to execute when the listbox was explicitly changed by the user. – David Spence Feb 14 '15 at 00:15