Button using ICommand does not get disabled?
Asked Answered
W

3

2

I have a button control in my wpf-mvvm application.

I use an ICommand property (defined in viewmodel) to bind the button click event to viewmodel.

I have -> execute and canexecute parameters for my ICommand implementation (RelayCommand).

Even if CanExecute is false...button is not disabled...WHEN button CONTENT is IMAGE

But, when button content is text..enable/disable works fine.

<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>
Writer answered 26/12, 2010 at 6:10 Comment(0)
C
15

Button does get disabled, its just that it doesn't affect rendering of the image. You will have to write a trigger in the style which changes the opacity of the image to .5 and you'll get the desired effect of button disabled like so:

<Style x:Key="imageButton" TargetType="Button">
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Opacity" Value=".5" />
            </Trigger>
        </Style.Triggers>
</Style>
Cuthbertson answered 26/12, 2010 at 7:24 Comment(5)
Do I have to declare a property "IsEnabled" in viewmodel ?..Or will it take that value by default from the canExecute ?Writer
IsEnabled is the property of button that changes automatically when you return false from CanExecuteCuthbertson
I have tried what you told me..It's giving some issues..please see the code available in my question above.Writer
I got the cause of err. I was using more then two tems inside content. Thanks alot.Writer
It would be nice to show how this plugs into the button for those of us who are not so good at WPF.Wattage
R
1

Thanks! Tried the suggested code after all my buttons. Didn't work. Tried to extract just the trigger and insert it in a generic button that all other buttons inherited from: worked like a charm! This code first:

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

Based on the code above I created buttons like this:

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

When buttons where disabled the images in them is automatically dimmed to 0.5 opacity.

Ritenuto answered 20/6, 2012 at 19:13 Comment(0)
E
0

You will need pixel shader effect (it is not as complicated as it sounds, it's just about adding an assembly reference an then you can use it as easily as any in-built WPF effect) in conjunction with trigger similar to the one Hasan Khan posted to show the disabled button images in grayscale.

Ethelynethene answered 26/12, 2010 at 8:50 Comment(5)
Surely using a FormatConvertedBitmap to convert to gray scale would be more straightforward than a pixel shader!Nebuchadnezzar
And that can be done from XAML? Also, pixel shader can handle anything, not just bitmaps. And can be applied application-wide without touching the controls. And is calculated on the GPU (unlike FormarConvertedBitmap), letting CPU and RAM concentrate on more important stuff.Dullard
Yes, that can be done pretty much from xaml: msdn.microsoft.com/en-us/library/…. Also, compiling the pixel shader requires a 500+ MB download of the DirectX SDK, involves a different coding language in HLSL, .fx and .ps files. So while I still want to get into pixel shaders some illuminated day, my vote clearly goes to FormatConvertedBitmap for ease of implementation. Here's what I ended up with: https://mcmap.net/q/282265/-grey-out-image-on-button-when-element-is-disabled-simple-and-beautiful-wayTrove
@adabyron You don't need any of that. The link I posted provides an assebly with a ready-to-use shader. Just ref the assembly and use the effect from XAML, no other code needed.Dullard
@MatějZábský I avoid additional (unmanaged) dependencies whenever I can, and keep code I might want to change inside my project. But if you're sure that's exactly what you need then I'm sure this pre-compiled shader in an assembly is a sensible solution as well.Trove

© 2022 - 2024 — McMap. All rights reserved.