0

I am very new to wpf and the problem as follows.

Buttons with images should really behave like those in WinForms - grayed out when disabled (so as some suggest setting opacity for an image isn't enough because it leaves colors).

So I found piece of code:

<Image RenderOptions.BitmapScalingMode="NearestNeighbor" Height="20" Width="20" 
                       Opacity="{Binding SelectedItem, Converter={StaticResource selectedItemPresent}}">
                    <Image.Source>
                        <FormatConvertedBitmap DestinationFormat="Gray8">
                            <FormatConvertedBitmap.Source>
                                <BitmapImage UriSource="Images/edit_info.png" />
                            </FormatConvertedBitmap.Source>
                        </FormatConvertedBitmap>
                    </Image.Source>
                    <Image.OpacityMask>
                        <ImageBrush>
                            <ImageBrush.ImageSource>
                                <BitmapImage UriSource="Images/edit_info.png">
                            </ImageBrush.ImageSource>
                        </ImageBrush>
                    </Image.OpacityMask>
                </Image> 

This yields a grayed out button and the job is half done. (Converter just returns either 1 or 0.3 based on databound item value.)

However what I really need is to gray it out only when selected item is null.

So, I have two questions. 1.How to apply all that ... stuff based on a data context value? May be create another converter. Then I'll have to do this declarative xaml programmatically? Or I can define some rule in xaml, so part will be valid only when the rule fires?

2.This should be done to several buttons - how can this logic can be factored out (I saw some style.xaml in relevant project - is that where to put it)?

Thanks for consideration.

Nickolodeon
  • 2,848
  • 3
  • 23
  • 38

1 Answers1

0

Why not base the Button's Image and/or Opacity on it's IsEnabled value in a DataTrigger?

<Style TargetType="{x:Type Button}">
    <Setter Property="Content" Value="{StaticResource DefaultImage}" />
    <Setter Property="Opacity" Value="1" />

    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Content" Value="{StaticResource DisabledImage}" />
            <Setter Property="Opacity" Value=".3" />
        </Trigger>
    </Style.Triggers>
</Style>

One of the biggest advantages of doing it this way is you are not tying your UI with any of your business logic. In WPF, buttons are frequently bound to Commands, and will automatically disable if the Command.CanExecute evaluates to false. You don't need to worry about that situation.

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Like I said, I am very new to WPF. So, how do I reference this style by those buttons that need it (not all of them) - I see there is a Style property on the button, but don't see anything like Name attribute in the Style tag. Also, the image is the same for one button, whether its enabled or disabled. Just need to gray it out. But I see your point - just move that to Style.Triggers, right? But then, every button has its own image source, so how do I substitute it in style? – Nickolodeon Jan 04 '12 at 19:29
  • @Nickolodeon You can give your style a key such as `` and then apply it to specific Buttons ` – Rachel Jan 04 '12 at 19:38
  • Actually I have something like – Nickolodeon Jan 04 '12 at 19:43