简体   繁体   English

将命令绑定到 ListView 项目 MVVM 的正确方式

[英]Binding Command to ListView Items MVVM proper way

I have an application list which is bound to a ListView control.我有一个绑定到 ListView 控件的应用程序列表。

private List<_Application> _applicationList;

public List<_Application> applicationList
{
    get { return _applicationList; }
    set
    {
        _applicationList = value;
        OnPropertyChanged();
    }
}

The ListView ItemTemplate is set as a button. ListView ItemTemplate 设置为按钮。

<ListView ItemsSource="{Binding applicationList}"
          BorderThickness="5"
          Style="{DynamicResource ListViewStyle}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Button Command="{Binding RunCommand}" 
                    Style="{StaticResource ApplicationButtonStyle}" 
                    Content="{Binding name}" 
                    Background="{Binding colorRGB}" >
            </Button>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

When I click on the button I want an application to be executed.当我单击按钮时,我希望执行一个应用程序。 My Model _Application contains an ActionCommand that runs the process.我的模型 _Application 包含一个运行该过程的 ActionCommand。

public class _Application
{
    public ActionCommand RunCommand
    {
        get { return new ActionCommand(action => Run()); }
    }

    private void Run()
    {
        Process p = new Process();
        p.StartInfo.FileName = path;

        try
        {
            p.Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    public _Application()
    {
    }
}

I am not sure, is it correct keeping the ActionCommand in the Model?我不确定,将 ActionCommand 保留在模型中是否正确?

How could I correctly implement this in the MVVM pattern?我怎样才能在 MVVM 模式中正确地实现这一点?

Where should the ActionCommand be placed and how to bind it to the ListView of Buttons so the correct _Application will be run? ActionCommand 应该放在哪里以及如何将它绑定到按钮的 ListView 以便运行正确的 _Application?

I think the best way is pass the model ( _Application ) like a parameter to the command.我认为最好的方法是将模型( _Application )像参数一样传递给命令。

RunCommand = new RelayCommand(param => this.OnRun(param));

Command action命令动作

private void OnRun(_Application app)
{
     //Any action with your model
}

Xaml xml

Command="{Binding DataContext.RunCommand, ElementName=PageRootKey}"
CommandParameter="{Binding Mode=OneWay}">

First of all you should use ICommand and not ActionCommand from one simple reason, if in the future you will want to replace the ActionCommand in something better that implements ICommand you won`t need to replace so many places in the code.首先,出于一个简单的原因,您应该使用 ICommand 而不是 ActionCommand,如果将来您想将 ActionCommand 替换为实现 ICommand 的更好的东西,您将不需要替换代码中的这么多地方。

    public ICommand RunCommand
    {
        get
        { return new ActionCommand(Run); }
    }

The correct _Application will run as each item in the list view is connected to single _Application item in the collection.正确的 _Application 将运行,因为列表视图中的每个项目都连接到集合中的单个 _Application 项目。

Note: in above code I wrote ...ActionCommand(Run);注意:在上面的代码中我写了 ...ActionCommand(Run); since ActionCommand accepts an Action parameter you can write the code shortly and more readable like this.由于 ActionCommand 接受一个 Action 参数,因此您可以像这样编写代码更短且更具可读性。

I assume of course in the complete code _Application has properties of name and colorRgb.我当然假设在完整的代码 _Application 具有 name 和 colorRgb 的属性。 As a matter of fact, if you wish to use correct MVVM pattern then colorRgb should not be in the viewmodel or the model.事实上,如果您希望使用正确的 MVVM 模式,那么 colorRgb 不应出现在视图模型或模型中。 It is a view term.它是一个视图术语。 You should use a converter (read IValueConverter) to set a different color for each button (although it is not UX friendly).您应该使用转换器(阅读 IValueConverter)为每个按钮设置不同的颜色(尽管它不是 UX 友好的)。

And one last thing, property like name should be Name (capital N) as property names in C# should always begin with capital letters.最后一件事,像 name 这样的属性应该是 Name(大写 N),因为 C# 中的属性名称应该始终以大写字母开头。

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

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