【问题标题】:WPF MVVM: How to disable clicked button and enable all other buttons?WPF MVVM:如何禁用单击的按钮并启用所有其他按钮?
【发布时间】:2019-02-01 17:45:37
【问题描述】:

我有一组按钮,只要单击其中一个按钮就会启用,而单击的那个按钮会被禁用。

<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>
<Button DockPanel.Dock="Top" Style="{StaticResource BigGrayButton}" Command="{Binding Path=NavigatePage}" IsEnabled="{Binding Path=EnableButton}"/>

问题是使用上述代码导致在执行命令后将 EnableButton 设置为 false 时禁用所有按钮。

【问题讨论】:

  • 通常,您只需确保CanExecute is false for that button。您真的将相同的命令绑定到所有按钮吗?如果是,您如何确定点击了哪一个(因为,我认为它会对您的应用产生影响)?如果所有按钮都完全相同,为什么你有 4 个而不是 1 个?
  • 试试RadioButton,很适合这种情况
  • 问题是所有按钮都被禁用了,但我想要的是只禁用单击的一个并启用所有其他按钮。
  • 那么每个按钮必须有一个命令?
  • @HmH:啊,我明白了,所以按钮基本上是用于选择要显示的页面的切换按钮,对吧?在这种情况下,最简单的解决方案是让CanExecute 返回false,如果参数等于当前显示的页面,否则true。你根本不需要IsEnabled

标签: c# wpf


【解决方案1】:

正如我所说,为什么不试试RadioButton

如果你只想实现这个“功能”,这太容易了——甚至不需要涉及MVVM

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <StackPanel.Resources>
        <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
        <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
        <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
        <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="BaseButtonStyle" TargetType="{x:Type RadioButton}">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="IsEnabled" Value="False"/>
                </Trigger>
            </Style.Triggers>
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <!--<Trigger Property="IsDefaulted" Value="true">
                            <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                        </Trigger>-->
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </StackPanel.Resources>
    <RadioButton Content="Button1" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button2" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button3" Style="{StaticResource BaseButtonStyle}"/>
    <RadioButton Content="Button4" Style="{StaticResource BaseButtonStyle}"/>
</StackPanel>

预览:


然后你可以为每个按钮设置CommandParameter来告诉后端代码哪个按钮被按下了。

您无需编写任何复杂的逻辑即可实现此功能。为什么不试试呢?

【讨论】:

  • +1 因为这不需要写出自定义逻辑,因为它已经实现了,并且它允许简单的样式。
  • 这似乎是代码最少的最佳解决方案,尽管我仍然希望使用 mvvm 使用常规按钮来实现此行为。
  • 这里有车,为什么要重新发明轮子? :-)
  • 补充一点:如果你真的想使用MVVM,请尝试在ListBox上写一个样式
猜你喜欢
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 2021-04-02
  • 2015-03-28
  • 2022-09-27
相关资源
最近更新 更多