ListBox.ContextMenu通过命令获取所选项

时间:2015-11-05 15:43:43

标签: wpf mvvm mvvm-light

我有这个观点:

<StackPanel>
<StackPanel.DataContext>
    <local:MainViewModel />
</StackPanel.DataContext>
<ListView ItemsSource="{Binding Persons}" x:Name="xamlPersonList">
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Header="EMail" Command="{Binding WriteMailCommand}" CommandParameter="{Binding ElementName=xamlPersonList,Path=SelectedItem}" />
        </ContextMenu>
    </ListBox.ContextMenu>
</ListView>
</StackPanel>

我想获取所选项目(或点击的项目),并在我的Command-Method中使用它做一些事情。这是我的ViewModel的Ctor和Command-Method:

public ICommand WriteMailCommand { get; private set; }
public MainViewModel()
{
    _persons = new ObservableCollection<Person>();
    for (int i = 0; i < 10; i++)
    {
        _persons.Add(new Person()
        {
            ID = i,
            Name = "Robert " + i
        });
    }

    WriteMailCommand = new RelayCommand<object>(WriteMailMethod);
}

private void WriteMailMethod(object obj)
{
}

obj参数始终为null。我不知道我在这里失踪了什么?!我尝试了这个解决方案:How to pass listbox selecteditem as command parameter in a button?

1 个答案:

答案 0 :(得分:3)

由于ContextMenu exists outside of your control's visual tree,绑定无法正常工作,因此无法找到ListBox。事实上,我很惊讶它没有通常的咒语来调用你的命令来获取相关控件的数据上下文:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >

无论如何,您可以使用answer suggested here,或者我可以建议替代实施:向您的视图模型添加SelectedPerson属性:

private Person selectedPerson;
public Person SelectedPerson 
{ 
    get { return selectedPerson; } 
    set
    {
        selectedPerson = value;
        RaisePropertyChanged(); // or whatever your implementation is
    }
}

你的XAML也很简单:

<ListView ItemsSource="{Binding Persons}" 
          SelectedItem="{Binding SelectedPerson}">
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Header="EMail" 
                      Command="{Binding WriteMailCommand}" 
                      CommandParameter="{Binding SelectedPerson}" />
        </ContextMenu>
    </ListBox.ContextMenu>
</ListView>