如何使用调用相同命令的多个复选框来减少代码

How to make less code with multiple checkboxes that call the same command

我目前正在做一个程序,我想要有多个复选框和多个按钮,其中每个按钮都绑定到一个复选框。启用复选框后,它应该隐藏特定按钮。

目前我可以通过一个按钮完成此操作:

<CheckBox Name="cbxIsClosableForUser"
     DataContext="{StaticResource GeneralVM}"
     Command="{Binding BtnToggleLblVisibilityDelegateCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
     CommandParameter="{Binding LblVisibilityCloseButton}"
     Content="{m:Translate ClosingAvailableForUser}" 
     Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3"
     Margin="6,0,0,0"
     HorizontalAlignment="Left" VerticalAlignment="Center" />

在另一个视图上有按钮:

<Button DataContext="{StaticResource GeneralVM}"
     Visibility="{Binding LblVisibilityCloseButton, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
     Style="{StaticResource NewButtonStyle}" 
     Grid.Column="3"
     Grid.Row="3"
     PreviewMouseDown="ImQuit_PreviewMouseDown"
     HorizontalAlignment="Right"
     VerticalAlignment="Bottom" >
     <Image Name="imQuit"
          Source="/CWI;component/Images/quit.png" 
     Stretch="None"/>
</Button>

这是 ViewModel 中的代码:

    public Visibility LblVisibilityCloseButton
    {
        get => _LblVisibilityCloseButton;
        set
        {
            OnPropertyChanged(nameof(LblVisibilityCloseButton)); 
            _LblVisibilityCloseButton = value;
        }
    }
    private Visibility _LblVisibilityCloseButton; 

    public GeneralViewModel()
    {
        LblVisibilityCloseButton = Visibility.Visible; 
        BtnToggleLblVisibilityDelegateCommand = new DelegateCommand<object>(ToggleVisibility); 
    }

    public DelegateCommand<object> BtnToggleLblVisibilityDelegateCommand { get; set; } 

    private void ToggleVisibility(object obj)
    {

        if (LblVisibilityCloseButton == Visibility.Visible)
        {
            LblVisibilityCloseButton = Visibility.Hidden;
        }
        else
        {
            LblVisibilityCloseButton = Visibility.Visible;
        }
    }

现在问题是这个复选框工作得很好。但我希望多个其他复选框调用相同的命令而不重复自己,并为 5 个附加按钮放置 5 个其他 if 语句。

编辑:我正在使用 MVVM,我不希望每个复选框都有代码隐藏。

您只需将 PreviewMouseDown= 设置为相同的方法即可。我希望我没记错,但是 e 类型 EventArgs 的变量可以包含有关调用该事件的按钮的信息。

忘记执行此操作的视图模型方式并使用纯 xaml 解决方案。

<CheckBox Name="cbxIsClosableForUser"/>
<Button Visibility="{Binding ElementName=cbxIsClosableForUser, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>

然后您需要做的就是编写实现 IValueConverter 接口的 BooleanToVisibilityConverter,将其作为应用程序资源加载,具体名称为 "BooleanToVisibilityConverter" 或者任何您想要的名称,这样就很好了去。

如果他们不在同一个视图中,但他们共享视图模型,则执行此操作

<CheckBox Name="cbxIsClosableForUser" IsChecked="{Binding IsClosableChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Visibility="{Binding IsClosableChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>

其中 IsClosableChecked 是您的视图模型布尔值 属性,视图模型应正确实现 INotifyPropertyChanged 接口,并通知 IsClosableChecked 属性 的 setter 中的更改。

您可以使用 RelayCommands。您可以 link 所有按钮到同一个命令,并从您的 xaml 文件传递​​一个附加的 CommandParamter。命令参数可以在您的虚拟机中处理。

你的XAML:

<Button x:Name"Button1" Command="{Binding MyCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" ..... />

虚拟机:

    RelayCommand _myCommand;
    public ICommand MyCommand
    {
        get
        {
            if (_myCommand== null)
            {
                _myCommand= new RelayCommand(param =>
                {
                    if(((Button)param).Name == "Button1"){
                          //Do what you wish to do with Button1 Click
                     }
                });
            }
            return _myCommand;
        }
    }

我没有运行这个代码。但是,解决方案是类似的。您可以将一些其他唯一参数传递给您的 VM,您可以在这些参数上区分哪个 Button 触发了此命令。我在我的参数中传递 Button 本身。您也可以使用 "clr-namespace:System;assembly=mscorlib"

传递整数等