wpf 带有 MVVM 和 CommandParameter 的 ListBox SelectionChanged 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36494209/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:44:51  来源:igfitidea点击:

ListBox SelectionChanged event with MVVM and CommandParameter

c#wpfxamlmvvmlistbox

提问by VansFannel

I'm developing a MVVM app with WPF, C# and .NET Framework 4.6.1.

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

I'm trying to implement ListBox SelectionChangedevent using MVVM. To do it I have done this:

我正在尝试ListBox SelectionChanged使用 MVVM实现事件。为此,我已经这样做了:

Install nuget package: PM> Install-Package System.Windows.Interactivity.WPF.
Add xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"on xaml.
Add this code to my ListBoxin xaml:

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

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

On ViewModel I have:

在 ViewModel 我有:

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

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

And DelegateCommandclass:

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
}

But my problem is that I don't know how to pass CommandParameter="{Binding ElementName=listBoxTrzType, Path=SelectedItem}"to private void TrzTypeSelectionChanged().

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

I've been searching a lot on Internet and I haven't found any example (only examples with CanExecute).

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

How do I have to modify my ViewModelclass to access SelectedItemparameter?

我必须如何修改我的ViewModel类才能访问SelectedItem参数?

回答by Dennis

Actually, to use interaction behaviors for such task is overkill.
You even don't need a command here. It's enough to add SelectedItemproperty into view model and listen for property changes:

实际上,将交互行为用于此类任务是矫枉过正的。
你甚至不需要这里的命令。将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:

XAML:

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

回答by XAMlMAX

In your DelegateCommand
change private readonly Action _action;to private readonly Action<object> _action;then in your execute method

在您DelegateCommand
更改private readonly Action _action;private readonly Action<object> _action;then 在您的执行方法中

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

Now your ViewModelfunction needs to look like this:

现在您的ViewModel函数需要如下所示:

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

And you are good to go.

你很高兴去。