如何将命令绑定添加到动态按钮?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将命令绑定添加到动态按钮?相关的知识,希望对你有一定的参考价值。

经过广泛的研究,我还没有找到这个问题的答案。我有一个列表框,其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;
        }
    }

我希望能帮助别人。

以上是关于如何将命令绑定添加到动态按钮?的主要内容,如果未能解决你的问题,请参考以下文章

JSF 动态绑定命令按钮

js如何给按钮添加点击事件

以编程方式将按钮添加到片段

如何将WPF中的命令绑定到控件的双击事件处理程序

C# 命令绑定

js 动态添加的按钮 onclick事件怎么写?