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

时间:2013-12-13 12:12:06

标签: c# wpf windows-phone-7

我想将命令参数设置为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#(暴露ListBoxClick命令的ViewModel代码的一部分)

public RelayCommand ListBoxClick { get; set; }

ListBoxClick = new RelayCommand((o) => {
    //model is always null
    var model = o as BasicModel;

    SelectedPlace = model;
});

我添加了适当的引用和命名空间:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

问题在于RelayCommand对象调用的操作中o参数始终为null。

更新

C# SelectedPlace属性

的代码
public BasicModel SelectedPlace {
            get {
                return _selectedPlace;
            }
            set {
                _selectedPlace = value;
                RaisePropertyChanged("SelectedPlace");
            }
        }

当我使用它时:

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

如果我第一次单击ListBoxItem,一切正常,但是当我点击选定的ListBoxItem时,没有任何反应,因为选择不会改变。我需要能够在两种情况下检测项目点击。

2 个答案:

答案 0 :(得分:0)

试试这个:

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

如果这不起作用,请尝试将Binding更改为:

CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Self}}"

更新&gt;&gt;&gt;

哦对不起,我没有看到您使用的是Windows Phone 7.另外,尝试在您的代码后面添加一个属性/ view模型,该属性绑定到ListBox.SelectedItem属性:

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

然后你应该能够做到这一点:

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

更新2&gt;&gt;&gt;

我不知道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>

答案 1 :(得分:0)

我想出了一个实现目标的丑陋方式。

<强> 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;
    }
});

在这两种情况下都会调用RaisePropertyChanged("SelectedPlace");