根据多个条件(开关机箱类型)启用WPF中的按钮

本文关键字:启用 WPF 按钮 类型 机箱 条件 开关 | 更新日期: 2023-09-27 18:14:32

我的xaml结构是这样的:

  1. 单选按钮和相应的控件,如果单选按钮被选中,将被启用。例如,如果选择了单选按钮food,那么将启用两个文本框,对于单选按钮Drinks,将启用一个组合框。
  2. 和一个按钮处理对话框中的数据。

我想仅在选中一个单选按钮并填充其相应控件时启用Button。我使用命令按钮在我的视图模型。请帮我做这件事。

按钮命令

    EnableProcessButton = new RelayCommand(ExecuteButton, CanExecuteButton);  
    public ICommand EnableProcessButton
    {
        get;
        internal set;
    }
    private bool CanExecuteButton(object obj)
    {
        switch (SelectedMode)
        {
            case "Drinks": return (!string.IsNullOrEmpty(SelectedDrink));
                break;
            case "Food": return ((!string.IsNullOrEmpty(text1)) && (text2 != default(int)));//The second text box is implemented as a numeric one
                break;                
            default: return false;
                break;
        }
    }
    private void ExecuteButton(object obj)
    {
        //DO the required things.
    }

Xaml

<StackPanel>
        <TextBox x:Name="FoodBox1"  Width="120" Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding ElementName=Food, Path=IsChecked}" UndoLimit="5"
                      Text="{Binding textbox1, UpdateSourceTrigger=PropertyChanged}" TextChanged="Foodbox1_TextChanged"/>
        <TextBox Name="FoodBox2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Margin="10" IsEnabled="{Binding ElementName=Food, Path=IsChecked}" UndoLimit="5"
                MaxLength="5" TextChanged="FoodBox2_TextChanged" Validation.ErrorTemplate="{x:Null}" Text="{Binding textbox2,  UpdateSourceTrigger=PropertyChanged}" />
 </StackPanel>
    <ComboBox Name="DrinkOptions" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Center"  VerticalAlignment="Center" Width="120" Margin="10" IsEnabled="{Binding ElementName=Drinks, Path=IsChecked}"
                  ItemsSource="{Binding AvailableDrinks}" SelectedValue="{Binding SelectedDrink}"/>

当某些内容被写入文本框然后被删除时,按钮不会被禁用。组合框没有问题。

根据多个条件(开关机箱类型)启用WPF中的按钮

这很容易做到

<StackPanel>
    <StackPanel.Resources>
        <BooleanToVisibilityConverter x:Key="VisibilityConverter" />
    </StackPanel.Resources>
    <GroupBox>
        <GroupItem>
            <StackPanel>
                <RadioButton Content="Food" x:Name="rdbFood" IsChecked="{Binding IsFoodProperty}" ></RadioButton>
                <RadioButton Content="Drinks" x:Name="rdbDrinks" IsChecked="{Binding IsDrinkProperty}"></RadioButton>
            </StackPanel>
        </GroupItem>
    </GroupBox>
    <TextBox Text="{Binding TextBox1}" Visibility="{Binding ElementName=rdbFood, Path=IsChecked, Converter={StaticResource VisibilityConverter}}"></TextBox>
    <TextBox Text="{Binding TextBox2}" Visibility="{Binding ElementName=rdbFood, Path=IsChecked, Converter={StaticResource VisibilityConverter}}"></TextBox>
    <ComboBox SelectedItem="{Binding SelectedDrink}" Visibility="{Binding ElementName=rdbDrinks, Path=IsChecked, Converter={StaticResource VisibilityConverter}}"></ComboBox>
    <Button Content="Submit" Command="{Binding EnableProcessButton}"></Button>
</StackPanel>

编辑

视图模型
    public string SelectedConMode { get; set; }
    private bool? _isFoodProperty;
    public bool? IsFoodProperty
    {
        get { return _isFoodProperty; }
        set
        {
            _isFoodProperty = value;
            if (value != null && (bool)value)
                SelectedConMode = "Food";
        }
    }
    private bool? _isDrinkProperty;
    public bool? IsDrinkProperty
    {
        get { return _isDrinkProperty; }
        set
        {
            _isDrinkProperty = value;
            if (value != null && (bool)value)
                SelectedConMode = "Drinks";
        }
    }

    private string _selectedDrink;
    public string SelectedDrink
    {
        get { return _selectedDrink; }
        set
        {
            _selectedDrink = value;
        }
    }
    private string _textBox1;
    public string TextBox1
    {
        get { return _textBox1; }
        set
        {
            _textBox1 = value;
        }
    }
    private int _textBox2;
    public int TextBox2
    {
        get { return _textBox2; }
        set
        {
            _textBox2 = value;
        }
    }

    public MainWindowViewModel()
    {
        IsFoodProperty = true;
        IsDrinkProperty = false;
        EnableProcessButton = new RelayCommand(() => ExecuteButton(null), () => CanExecuteButton(null));
    }
    public ICommand EnableProcessButton
    {
        get;
        internal set;
    }
    private bool CanExecuteButton(object obj)
    {
        switch (SelectedConMode)
        {
            case "Drinks":
                return (!string.IsNullOrEmpty(SelectedDrink));
            case "Food":
                return ((!string.IsNullOrEmpty(_textBox1)) && (_textBox2 != default(int)));
            default:
                return false;
        }
    }
    private void ExecuteButton(object obj)
    {
        //DO the required things.
    }
    public event PropertyChangedEventHandler PropertyChanged;
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

以防您没有将CanExecuteChanged事件挂接到CommandManager的RequerySuggested:

public event EventHandler CanExecuteChanged
{
   add { CommandManager.RequerySuggested += value; }
   remove { CommandManager.RequerySuggested -= value; }
}

关于这个的更多信息,请看这里:

https://joshsmithonwpf.wordpress.com/2008/06/17/allowing-commandmanager-to-query-your-icommand-objects/

我在两个文本框的TextChanged事件处理程序中设置的viewmodel中声明了两个booleansCanExecute函数变为

private bool CanExecuteButton(object obj)
{
    switch (SelectedMode)
    {
        case "Drinks": return (!string.IsNullOrEmpty(SelectedDrink));
            break;
        case "Food": return (enableButtonFoodbox1 && enableButtonFoodbox2);//These two booleans are initialized to false and set to true in the TextChangedEvent Handlers of the two textboxes
            break;                
        default: return false;
            break;
    }
}

现在,它工作正常。谢谢。