简体   繁体   English

将CommandParameter设置为ListBox(WP7)上当前点击的项目

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

I want to set command parameter to currently selected item on a ListBox. 我想将命令参数设置为ListBox上当前选定的项目。

XAML: 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) C# (公开ListBoxClick命令的ViewModel代码的一部分)

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. 问题在于,在由RelayCommand对象调用的RelayCommando参数始终为null。

UPDATE UPDATE

C# code for SelectedPlace property SelectedPlace属性的C#代码

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. 如果我第一次单击ListBoxItem,一切正常,但是当我单击选定的ListBoxItem时,什么也没有发生,因为选择不会更改。 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: 如果这不起作用,请尝试将Binding更改为此:

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: 抱歉,我没有看到您使用的是Windows Phone7。或者,尝试将属性添加到绑定到ListBox.SelectedItem属性的后台代码/视图模型中:

<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedItem}" ... />

Then you should be able to do this: 然后,您应该可以执行以下操作:

ListBoxClick = new RelayCommand(() => {
    SelectedPlace = SelectedItem;
});

UPDATE 2 >>> 更新2 >>>

I don't know if Windows Phone 7 supports the Binding.ElementName property, but if it does, try this: 我不知道Windows Phone 7是否支持Binding.ElementName属性,但是如果支持,请尝试以下操作:

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

<ListBox ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedPlace, Mode=TwoWay}">

C# (ViewModel) 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"); 这样RaisePropertyChanged("SelectedPlace"); will be called in both cases. 在两种情况下都会被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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