经过广泛的研究,我还没有找到这个问题的答案。我有一个列表框,其ItemsSource是Button对象的集合。当我向集合添加一个按钮时,它会正确显示,但是当单击时,该命令不会被执行。我已经实现了RelayCommand,它在我的代码中使用。
C#MVVM WPF
风景
<ListBox ItemsSource="{Binding Buttons}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Margin="5,5,5,5"
Content="{Binding Content}"
Command="{Binding ExecuteButtonCommand}"
CommandParameter="{Binding CommandParameter}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
ViewModel
public RelayCommand _executeButtonCommand;
public ICommand ExecuteButtonCommand
{
get
{
if (_executeButtonCommand == null)
_executeButtonCommand = new RelayCommand(exec => this.ButtonCommands(param));
return _executeButtonCommand;
}
}
对于测试我有这个代码。
public void AddButtons()
{
Buttons= new ObservableCollection<Button>();
Button btn = new Button();
btn.Content = "Generate Files";
btn.Command = "{Binding ExecuteButtonCommand}";
btn.CommandParameter = "Files";
Buttons.Add(btn);
}
但我无法以这种方式分配命令。按钮的其余部分正常工作。所以我把Command =放在视图中,如上所示。
如果这已得到回答,那么我找不到它。最近的答案是9岁,不起作用。
谢谢你的期待。
发生的事情是ListBox的DataTemplate试图绑定到一个名为ExecuteButtonCommand的属性,该属性在Button对象中不存在。然后,要绑定参数,您需要指向视图的DataContext。
将其更改为:
<ListBox.ItemTemplate>
<DataTemplate>
<Button Margin="5,5,5,5"
Content="{Binding Content}"
Command="{Binding Command}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.MyParameter}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
为了澄清,我在ViewModel中创建了一个名为“MyParameter”的属性。此外,在您的代码隐藏中,将按钮创建代码更改为:
Buttons = new ObservableCollection<Button>();
Button btn = new Button();
btn.Content = "Generate Files";
btn.Command = ExecuteButtonCommand;
Buttons.Add(btn);
而你的ExecuteButtonCommand简单地说:
public ICommand ExecuteButtonCommand
{
get
{
if (_executeButtonCommand == null)
_executeButtonCommand = new RelayCommand(ButtonCommands);
return _executeButtonCommand;
}
}
我希望用最终结果将其关闭,以防其他人正在寻找相同的答案。 Mari让我直截了当,导致下面这个例子作为最终结果。没有“背后的代码”。按钮的生成在视图模型中完成。创建按钮后,它将添加到按钮集合中,该集合是ListBox的源。我只包含特定于该问题的代码。
这就是最终结果。
风景
<ListBox ItemsSource="{Binding Buttons, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="AliceBlue"
BorderBrush="Transparent"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedItem="">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Margin="5,5,5,5"
Content="{Binding Content}"
Command="{Binding Command}"
CommandParameter="{Binding CommandParameter}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
ViewModel - 一个switch语句用于确定需要生成哪个按钮。我给了按钮一个名字,因为我希望能够在集合中找到它并设置Enabled属性。但这没用,我仍然没有找到答案。
public void AddButton(string param)
{
Button btn = new Button();
switch (param)
{
case "Files":
btn.Content = "Do Files";
btn.CommandParameter = "Files";
btn.Name = "Files";
break;
//More items here
}
btn.Command = ExecuteButtonCommand; //The ICommand name. I made this harder than it needed to be!
Buttons.Add(btn);
}
public RelayCommand _executeButtonCommand;
public ICommand ExecuteButtonCommand
{
get
{
if (_executeButtonCommand == null)
_executeButtonCommand = new RelayCommand(param => this.ButtonCommands(param));
return _executeButtonCommand;
}
}
我希望能帮助别人。