I want to set command parameter to currently selected item on a ListBox.
XAML:
<!--<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedPlace, Mode=TwoWay}">-->
<ListBox ItemsSource="{Binding Places}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ListBoxClick}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
(...)
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C# (part of ViewModel code exposing the ListBoxClick command)
public RelayCommand ListBoxClick { get; set; }
ListBoxClick = new RelayCommand((o) => {
//model is always null
var model = o as BasicModel;
SelectedPlace = model;
});
I added appropriate references, and namespace:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
The problem is that in action called by RelayCommand
object the o
parameter is always null.
UPDATE
C# code for SelectedPlace
property
public BasicModel SelectedPlace {
get {
return _selectedPlace;
}
set {
_selectedPlace = value;
RaisePropertyChanged("SelectedPlace");
}
}
When I use this:
<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedPlace, Mode=TwoWay}">
everything works fine if I click ListBoxItem for the first time, but when I click on a selected ListBoxItem nothing happens, because selection doesn't change. I need to be able to detect item click in both situations.
Try this:
<ListBox ItemsSource="{Binding Places}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ListBoxClick}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType={
x:Type ListBox}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
(...)
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If that doesn't work, try changing the Binding
to this:
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Self}}"
UPDATE >>>
Oh sorry, I didn't see that you were using Windows Phone 7. As an alternative, try adding a property into your code behind/view model that binds to the ListBox.SelectedItem
property:
<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedItem}" ... />
Then you should be able to do this:
ListBoxClick = new RelayCommand(() => {
SelectedPlace = SelectedItem;
});
UPDATE 2 >>>
I don't know if Windows Phone 7 supports the Binding.ElementName
property, but if it does, try this:
<ListBox Name="ListBox" ItemsSource="{Binding Places}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding ListBoxClick}"
CommandParameter="{Binding SelectedItem, ElementNameListBox}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
(...)
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I figured out an ugly way to achieve my goal.
XAML
<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedPlace, Mode=TwoWay}">
C# (ViewModel)
private bool _placeSelected;
public BasicModel SelectedPlace {
get {
return _selectedPlace;
}
set {
_placeSelected = true;
_selectedPlace = value;
RaisePropertyChanged("SelectedPlace");
}
}
ListBoxClick = new RelayCommand((o) => {
if (!_placeSelected) {
SelectedPlace = _selectedPlace;
}
else {
_placeSelected = false;
}
});
This way RaisePropertyChanged("SelectedPlace");
will be called in both cases.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.