我有一个ICommands循环(好吧,RelayCommand继承自ICommand),我不知道如何向每个ICommand提供信息。
我实际上在做的是创建一个WPF上下文菜单,每个菜单项都有一个ICommand。每个菜单项都需要做不同的事情。它需要将点击的项目(角色)添加到一组项目(场景)。
如果我展示循环本身,我会更清楚:
foreach (Scene s in Database.Instance.Scenes)
{
SceneAddMenu.Add(new ContextMenuVM()
{
DisplayName = s.SceneName,
ContextMenuCommand = new RelayCommand(
() =>
{
MessageBox.Show("Clicked " + s.SceneID.ToString());
})
});
}
ContextMenuVM包含一个String(菜单项显示文本)和ContextMenuCommand,它是一个RelayCommand(继承自ICommand)。
目前,代码始终使用列表中的最终场景ID运行。我认为这是因为表达式是在运行时进行评估的(我可能完全错了),所以它总是在循环结束时。
我想要的是从每个循环外部(场景')获取信息到循环内部。
我对此问题的了解不够充分。我已经搜索了ICommand循环'直到我在谷歌面前脸红,但我不认为这些是我问题的正确关键词。
任何帮助都会受到赞赏,即使只是用于搜索的正确术语。
答案 0 :(得分:0)
是的!这是捕获变量的问题。所有内存引用都更新为保持的最后一个值变量。你将不得不稍微调整一下,但这里有一个想法可以采取/尝试的替代方案。
public class Program {
public void Main() {
var commands = new List<MenuCommand>();
// Add commands
for (int i = 1; i <= 3; i++) {
commands.Add(new MenuCommand(MenuItemAction) { SceneId = i });
}
// Exec commands - Test
foreach (var cmd in commands) {
cmd.Execute(cmd.SceneId);
}
}
public void MenuItemAction(object sceneId) {
Console.WriteLine("Clicked: " + sceneId);
}
}
public class MenuCommand : RelayCommand {
public int SceneId { get; set; }
public MenuCommand(Action<object> action) :
base(action) {
}
}
public class RelayCommand : ICommand {
private Action<object> action;
public RelayCommand(Action<object> action) {
this.action = action;
}
public virtual void Execute(object parameter) {
this.action(parameter);
}
}
答案 1 :(得分:0)
在循环中创建SceneID
的副本:
foreach (Scene s in Database.Instance.Scenes)
{
int id = s.SceneID;
SceneAddMenu.Add(new ContextMenuVM()
{
DisplayName = s.SceneName,
ContextMenuCommand = new RelayCommand(
() =>
{
MessageBox.Show("Clicked " + id.ToString());
})
});
}