【问题标题】:How do I add the command binding to a dynamic button?如何将命令绑定添加到动态按钮?
【发布时间】:2018-08-01 08:36:18
【问题描述】:

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

视图模型

    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 岁,无效。

感谢收看。

【问题讨论】:

    标签: c# button mvvm command


    【解决方案1】:

    发生的情况是 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;
         }
     }
    

    【讨论】:

    • 太棒了,玛丽!由于我尝试了所有不同的方法,我的问题的参数部分搞砸了。我将 btn.CommandParameter = 放回按钮创建中。它工作得很好。现在我可以继续添加其余的按钮。我想我已经接近解决方案了。但一切都只是有点不对劲。现在我明白那是什么了。再次感谢您。
    • 好!很高兴它有帮助! :)
    【解决方案2】:

    我想用最终结果结束这个问题,以防其他人正在寻找相同的答案。 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;
            }
        }
    

    希望对大家有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多