使用MVVM和CommandParameter

时间:2016-04-08 07:43:53

标签: c# wpf xaml mvvm listbox

我正在使用WPF,C#和.NET Framework 4.6.1开发MVVM应用程序。

我尝试使用MVVM实现ListBox SelectionChanged事件。为此,我做到了这一点:

安装nuget包:PM> Install-Package System.Windows.Interactivity.WPF
在xaml上添加xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity" 将此代码添加到xaml中的ListBox

<ListBox x:Name="listBoxTrzType" Grid.Column="1" Margin="10,0,25,0" VerticalAlignment="Center" Height="25" ItemsSource="{Binding TrzTypes}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <interactivity:Interaction.Triggers>
        <interactivity:EventTrigger EventName="SelectionChanged">
            <interactivity:InvokeCommandAction Command="{Binding ListBoxTrzTypeSelectionChanged}"
                                                CommandParameter="{Binding ElementName=listBoxTrzType, Path=SelectedItem}">
            </interactivity:InvokeCommandAction>
        </interactivity:EventTrigger>
    </interactivity:Interaction.Triggers>
</ListBox>

在ViewModel上我有:

public ICommand ListBoxTrzTypeSelectionChanged
{
    get { return new DelegateCommand(TrzTypeSelectionChanged); }
}

private void TrzTypeSelectionChanged()
{
    throw new NotImplementedException();
}

DelegateCommand课程:

public class DelegateCommand : ICommand
{
    private readonly Action _action;

    public DelegateCommand(Action action)
    {
        _action = action;
    }

    public void Execute(object parameter)
    {
        _action();
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

#pragma warning disable 67
    public event EventHandler CanExecuteChanged { add { } remove { } }
#pragma warning restore 67
}

但我的问题是我不知道如何将CommandParameter="{Binding ElementName=listBoxTrzType, Path=SelectedItem}"传递给private void TrzTypeSelectionChanged()

我在互联网上搜索了很多,但我找不到任何例子(只有CanExecute的例子)。

如何修改ViewModel课程以访问SelectedItem参数?

2 个答案:

答案 0 :(得分:6)

实际上,对这种任务使用交互行为是过度的 你甚至不需要这里的命令。将SelectedItem属性添加到视图模型中并监听属性更改就足够了:

public class SomeVm : INotifyPropertyChanged
{
    // INPC implementation is omitted

    public IEnumerable<SomeType> Items { get; }
    public SomeType SelectedItem
    {
        get { return selectedItem; }
        set
        {
            if (selectedItem != value)
            {
                selectedItem = value;
                OnPropertyChanged();
                // do what you want, when property changes
            }
        }
    }
}

XAML:

<ListBox ItemsSource="{Binding Items}"
         SelectedItem="{Binding SelectedItem}"
         DisplayMemberPath="Name"/>

答案 1 :(得分:0)

DelegateCommand中 然后在执行方法中将private readonly Action _action;更改为private readonly Action<object> _action;

public void Execute(object parameter)
{
    _action.Invoke(parameter);
}  

现在,您的ViewModel功能需要如下所示:

private void TrzTypeSelectionChanged(object parameter)
{
    throw new NotImplementedException();
}  

你很高兴。