简体   繁体   中英

Set CommandParameter to currently tapped item on a ListBox (WP7)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM