将命令绑定到 ListView 项目 MVVM 正确的方式
Binding Command to ListView Items MVVM proper way
我有一个绑定到 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 将是 运行?
我认为最好的方法是将模型 (_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}">
首先,出于一个简单的原因,您应该使用 ICommand 而不是 ActionCommand,如果将来您希望将 ActionCommand 替换为实现 ICommand 的更好的东西,您将不需要替换代码中的那么多地方.
public ICommand RunCommand
{
get
{ return new ActionCommand(Run); }
}
正确的 _Application 将 运行 因为列表视图中的每个项目都连接到集合中的单个 _Application 项目。
注意:在上面的代码中我写了...ActionCommand(运行);由于 ActionCommand 接受一个 Action 参数,您可以像这样快速编写代码并提高可读性。
我当然假设在完整代码中 _Application 具有 name 和 colorRgb 属性。
事实上,如果你想使用正确的 MVVM 模式,那么 colorRgb 不应该在视图模型或模型中。这是一个视图术语。您应该使用转换器(阅读 IValueConverter)为每个按钮设置不同的颜色(尽管它对用户体验不友好)。
最后一件事,属性 名称应为名称(大写 N),因为 属性 C# 中的名称应始终以大写字母开头。
我有一个绑定到 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 将是 运行?
我认为最好的方法是将模型 (_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}">
首先,出于一个简单的原因,您应该使用 ICommand 而不是 ActionCommand,如果将来您希望将 ActionCommand 替换为实现 ICommand 的更好的东西,您将不需要替换代码中的那么多地方.
public ICommand RunCommand
{
get
{ return new ActionCommand(Run); }
}
正确的 _Application 将 运行 因为列表视图中的每个项目都连接到集合中的单个 _Application 项目。
注意:在上面的代码中我写了...ActionCommand(运行);由于 ActionCommand 接受一个 Action 参数,您可以像这样快速编写代码并提高可读性。
我当然假设在完整代码中 _Application 具有 name 和 colorRgb 属性。 事实上,如果你想使用正确的 MVVM 模式,那么 colorRgb 不应该在视图模型或模型中。这是一个视图术语。您应该使用转换器(阅读 IValueConverter)为每个按钮设置不同的颜色(尽管它对用户体验不友好)。
最后一件事,属性 名称应为名称(大写 N),因为 属性 C# 中的名称应始终以大写字母开头。