【问题标题】:Button using ICommand does not get disabled?使用 ICommand 的按钮不会被禁用?
【发布时间】:2023-03-16 04:20:02
【问题描述】:

我的 wpf-mvvm 应用程序中有一个按钮控件。

我使用ICommand 属性(在视图模型中定义)将按钮点击事件绑定到视图模型。

我的 ICommand 实现 (RelayCommand) 有 -> 执行和 canexecute 参数。

即使CanExecute 为假...按钮未被禁用...当按钮内容为图像时

但是,当按钮内容是 text..enable/disable 工作正常。

<Button DockPanel.Dock="Top" 
                        Command="{Binding Path=MoveUpCommand}">
                    <Button.Content>
                        <Image Source="/Resources/MoveUpArrow.png"></Image>
                    </Button.Content>
                    <Style>
                        <Style.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Opacity" Value=".5" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Button>

【问题讨论】:

    标签: wpf mvvm icommand canexecute


    【解决方案1】:

    按钮确实被禁用了,只是它不影响图像的渲染。 您必须编写一个触发器,将图像的不透明度更改为 0.5,您将获得所需的按钮禁用效果,如下所示:

    <Style x:Key="imageButton" TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Opacity" Value=".5" />
                </Trigger>
            </Style.Triggers>
    </Style>
    

    【讨论】:

    • 我是否必须在 viewmodel 中声明一个属性“IsEnabled”?.. 还是默认情况下它会从 canExecute 中获取该值?
    • IsEnabled 是按钮的属性,当您从 CanExecute 返回 false 时会自动更改
    • 我已经尝试过你告诉我的......它给出了一些问题......请参阅上面我的问题中提供的代码。
    • 我找到了错误的原因。我在内容中使用了两个以上的术语。非常感谢。
    • 很高兴为我们这些不擅长 WPF 的人展示它是如何插入按钮的。
    【解决方案2】:

    谢谢!在我的所有按钮之后尝试了建议的代码。没用。试图只提取触发器并将其插入所有其他按钮继承自的通用按钮中:就像一个魅力!先上这段代码:

    <Style x:Key="SecButton" TargetType="Button">
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Margin" Value="0,0,5,5" />
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Opacity" Value=".5" />
            </Trigger>
        </Style.Triggers>
    </Style>
    

    根据上面的代码,我创建了这样的按钮:

    <Style x:Key="NewBtnStyle" TargetType="Button" BasedOn="{StaticResource SecButton}">                
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Images/new.png" Width="50" Height="50" />
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    当按钮被禁用时,其中的图像会自动变暗为 0.5 不透明度。

    【讨论】:

      【解决方案3】:

      您将需要pixel shader effect(它并不像听起来那么复杂,它只是添加一个程序集引用,然后您可以像使用任何内置 WPF 效果一样轻松地使用它)以及类似于触发器的触发器Hasan Khan 发布以灰度显示禁用按钮图像。

      【讨论】:

      • 使用FormatConvertedBitmap 转换为灰度肯定比像素着色器更直接!
      • 这可以通过 XAML 完成吗?此外,像素着色器可以处理任何东西,而不仅仅是位图。并且可以在应用程序范围内应用,而无需触摸控件。并且是在 GPU 上计算的(与 FormarConvertedBitmap 不同),让 CPU 和 RAM 专注于更重要的事情。
      • 是的,这几乎可以从 xaml 完成:msdn.microsoft.com/en-us/library/…。此外,编译像素着色器需要 500+ MB 的 DirectX SDK 下载,涉及 HLSL、.fx 和 .ps 文件中的不同编码语言。因此,虽然我仍然想在某个光明的日子进入像素着色器,但我的投票显然是为了便于实施 FormatConvertedBitmap。这是我最终得到的结果:stackoverflow.com/a/25511558/385995
      • @adabyron 你不需要这些。我发布的链接提供了一个带有现成着色器的组件。只需引用程序集并使用 XAML 中的效果,无需其他代码。
      • @MatějZábský 我尽可能避免其他(非托管)依赖项,并将我可能想要更改的代码保留在我的项目中。但是,如果您确定这正是您所需要的,那么我相信程序集中的这个预编译着色器也是一个明智的解决方案。
      猜你喜欢
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      相关资源
      最近更新 更多