【问题标题】:Binding Command to ListView Items MVVM proper way以正确的方式将命令绑定到 ListView Items MVVM
【发布时间】:2017-01-26 08:57:35
【问题描述】:

我有一个绑定到 ListView 控件的应用程序列表。

private List<_Application> _applicationList;

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

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>

当我单击按钮时,我希望执行应用程序。我的模型 _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()
    {
    }
}

我不确定,将 ActionCommand 保留在模型中是否正确?

如何在 MVVM 模式中正确实现这一点?

ActionCommand 应该放在哪里以及如何将它绑定到 Buttons 的 ListView 以便运行正确的 _Application?

【问题讨论】:

    标签: c# wpf mvvm binding icommand


    【解决方案1】:

    我认为最好的方法是将模型 (_Application) 像参数一样传递给命令。

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

    命令动作

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

    Xaml

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

    【讨论】:

    • 感谢您的回答。那会起作用,但是我不知道如何确定应该将哪些 _Applications 传递给命令操作? ListView.SelectedItem 不起作用,因为我只单击一个按钮,而不是选择项目然后单击。
    • 据我了解,您想将 SelectedItem 传递给命令。 CommandParameter="{Binding SelectedItem, ElementName=ListViewName}"
    • 不,我没有,我只是错过了 CommandParameter。一切正常。非常感谢。
    【解决方案2】:

    首先,出于一个简单的原因,您应该使用 ICommand 而不是 ActionCommand,如果将来您想用更好的实现 ICommand 的方式替换 ActionCommand,则无需在代码中替换这么多地方。

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

    正确的 _Application 将运行,因为列表视图中的每个项目都连接到集合中的单个 _Application 项目。

    注意:在上面的代码中我写了 ...ActionCommand(Run);由于 ActionCommand 接受一个 Action 参数,您可以像这样编写代码更短且更具可读性。

    我当然假设在完整的代码中_Application 具有name 和colorRgb 的属性。 事实上,如果您希望使用正确的 MVVM 模式,那么 colorRgb 不应该在视图模型或模型中。这是一个视图术语。您应该使用转换器(阅读 IValueConverter)为每个按钮设置不同的颜色(尽管它对 UX 不友好)。

    最后一件事,像 name 这样的属性应该是 Name(大写 N),因为 C# 中的属性名称应该总是以大写字母开头。

    【讨论】:

    • 感谢您的回答。你是对的,使用 ICommand 会更好,我会纠正这一点。但是我应该将命令保留在模型中吗?
    • 当然。如果每个模型的操作不同,则命令的位置在模型中。
    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 2014-09-01
    • 2021-02-02
    • 1970-01-01
    • 2014-06-27
    • 2011-04-04
    • 1970-01-01
    相关资源
    最近更新 更多