我已经看到了很多使用MVVM Light中的RelayCommand类通过命令传递参数的例子,但是我想要的和我看到的之间有一点点差异。
我想创建一些按钮,其中所有按钮都与ModuleType相关联。当他们的行动被执行时,我想知道它是哪个ModuleType。我想以一种代码有效的方式做到这一点,所以不必手动创建RelayCommands,而是在foreach循环中完成所有操作,也因为我不知道我必须在开始时创建多少个按钮。
所以这是代码。在我的 ViewModel
中public ModuleSelectionViewModel(MachineStatusModel model, int order, List<ModuleType> modules) : base(model)
{
........
// create button for each of the modules
foreach (ModuleType mod in modules)
{
_navBarButtons.Add(new NavButton(mod.ToString(), new RelayCommand<ModuleType>(exec => ButtonExecute(mod)), mod));
}
RaisePropertyChanged("NavBarButtons");
}
// Binding to the Model
public ObservableCollection<NavButton> NavBarButtons
{
get { return _navBarButtons; }
}
// Execut Action
public void ButtonExecute(ModuleType mod)
{
WriteToLog("Selected " + mod.ToString());
}
// Support class
public class NavButton
{
public string ButtonContent { get; set; }
public ICommand ButtonCommand { get; set; }
public ModuleType ButtonModuleType;
public NavButton(string content, ICommand relay, ModuleType moduleType)
{
this.ButtonContent = content;
this.ButtonCommand = relay;
this.ButtonModuleType = moduleType;
}
}
我还在学习lambda表达式,所以我想我在RelayCommand的初始化上做错了。
答案 0 :(得分:2)
如果你执行10,10,10,10,10,10,10,10,10,10
循环并在lambda表达式中使用循环变量,则会捕获它。不幸的是,变量的范围不正确(至少在旧版本的C#中,changes with C# 5(谢谢,Mafii))。
所以你需要做一些事情:
foreach
答案 1 :(得分:0)
关于解决方案H.B.发布:不确定为什么它不能处理lambda函数,为什么ButtonExecute在按下按钮时没有被执行。而且我也不理解定义像'foo =&gt;这样的lambda函数的逻辑。当foo为空并传递给函数时,ButtonExecute(foo)'。但无论如何......
这就是我所做的并且正在发挥作用:
<强>模型强>
<ItemsControl Name="NavButtonsItemsControl" ItemsSource="{Binding NavBarButtons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding ButtonContent}" CommandParameter="{Binding ButtonModuleType}" Command="{Binding ButtonCommand}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel (检查我最初问题中的其余代码)
.........
_navBarButtons.Add(new NavButton(mod.ToString(), new RelayCommand<ModuleType>(ButtonExecute), type));
.........
private void ButtonExecute(ModuleType state)
{
WriteToLog("Command with parameter " + state.ToString());
}
您可以使用Object而不是ModuleType使其更通用。而不是使用lambda函数的解决方案是在按钮中定义CommandParameter绑定并将该值作为execute函数中的参数。我不认为绑定是明确定义的,这就是为什么我很难理解值是如何达到'ButtonExecute'的原因,但是遵循Dominik Schmidt tutorial中的步骤它有效。