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>
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Relativity
  • 6,690
  • 22
  • 78
  • 128

3 Answers3

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>
Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131
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.

aeinstein
  • 73
  • 1
  • 1
  • 7
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.

Matěj Zábský
  • 16,909
  • 15
  • 69
  • 114
  • 1
    Surely using a [FormatConvertedBitmap](http://www.c-sharpcorner.com/UploadFile/mahesh/317/Default.aspx) to convert to gray scale would be more straightforward than a pixel shader! – Tim Lloyd Dec 26 '10 at 20:37
  • 2
    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. – Matěj Zábský Dec 26 '10 at 20:58
  • 1
    Yes, that can be done pretty much from xaml: http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.formatconvertedbitmap%28v=vs.110%29.aspx. 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: http://stackoverflow.com/a/25511558/385995 – Mike Fuchs Aug 26 '14 at 17:26
  • @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. – Matěj Zábský Aug 27 '14 at 07:04
  • @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. – Mike Fuchs Aug 27 '14 at 11:08