2017-01-26 47 views
3

我有一个绑定到ListView的应用程序列表。将命令绑定到ListView项MVVM正确的方式

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() 
     { 
     } 
} 

我不确定在Model中保留ActionCommand是否正确?如何在MVVM模式下正确实现这个? ActionCommand应该放在哪里,以及如何将它绑定到Button的ListView,这样正确的_Application将会运行?

回答

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}"> 
+0

谢谢你的回答。这将工作,但我不知道如何确定哪些_应用程序应传递给命令行动? ListView.SelectedItem不起作用,因为我只点击一个按钮,而不是选择项目,然后单击。 – Crekate

+0

据我所知,你想通过'SelectedItem'到命令​​。 'CommandParameter =“{Binding SelectedItem,ElementName = ListViewName}”' –

+0

不,我没有,我刚刚错过了CommandParameter。一切都很好。非常感谢。 – Crekate

0

首先,你应该使用的ICommand,而不是从一个简单的原因ActionCommand,如果将来你会想更换ActionCommand在实现ICommand的更好的东西中,您不需要替换代码中的很多地方。

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

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

注意:在上面的代码中我写道... ActionCommand(Run);因为ActionCommand接受一个Action参数,所以你可以很快写出代码并且像这样更具可读性。

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

而最后一件事,就像名字属性应该是名称(大写N)在C#属性名称应始终以大写字母开头。

+0

谢谢你的回答。你说得对,使用ICommand会更好,我会纠正这一点。但是,我应该保持模型中的命令? – Crekate

+0

当然。如果操作是每个模型不同,那么命令的地方是在模型中。 –