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

时间:2015-09-25 06:22:58

标签: c# wpf

我的xaml结构是这样的:

  1. 单选按钮和相应的控件,如果选中单选按钮,将启用它们。例如,如果选择单选按钮食物,则将启用两个文本框,对于单选按钮饮料,将启用组合框。
  2. 用于处理对话框中数据的按钮。
  3. 我想只在选择了一个单选按钮并且填充了相应的控件时启用了按钮。 我在视图模型中使用了一个按钮命令。请帮我这样做。

    按钮的命令

        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}"/>
    

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

3 个答案:

答案 0 :(得分:0)

这很容易做到

<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));
    }
}

答案 1 :(得分:0)

万一您还没有将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/

答案 2 :(得分:0)

我在booleans中声明了两个viewmodel,它们是在两个文本框的TextChanged事件处理程序中设置的。 CanExecute函数变为

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;
    }

}

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