views:

132

answers:

2

So I'm styling a ListBox and I've got to the part where I need to do a greyed out style when the ListBox is disabled. However when I look a the states tab in Blend, there's only Validation States present - no sign of the usual Common States which include the Disabled state.

I tried creating a vanilla project with no custom styles and just a ListBox and the same thing happens. My question is, how do I go about styling a disabled state for a ListBox? Am I missing something obvious??

+1  A: 
Klinger
+1  A: 

First tried the simple approach: Edit the ListBoxItem template, rather than the List box. It is the items that are displayed in disabled state, not the listbox.

In blend: "Edit Additional Templates" > "Edit Generated Item Container (ItemContainerStyle)" > Edit a copy.

As a test I forced the background colour to red in the disabled state (see picture below). The background colour is normally derived from the parent list. The XAML is too big to list here.

An item container in a listbox consists of a grid containing 3 rectangles (to give the border colour effects) and a content container to hold the actual item content.

  • fillcolor
  • fillcolor2
  • contentPresenter
  • FocusVisualElement

Sample output

Obvious problem... all the white-space under the items. Bah! Must be a better way.

Now try to change the ListBox template instead: To change the template of the ListBox itself I thought you might be able to bind the background colour of the scrollviewer within the ListView Template to the IsEnabled property of the control. This would require a custom value converter (to convert the IsEnabled bool? to a Brush object), but they are pretty simple to create.

TemplateBinding does not support a convertor, but I found that you can use a normal binding in a template, if you use a RelativeSource:

<ScrollViewer x:Name="ScrollViewer" BorderBrush="Transparent" BorderThickness="0" Background="{Binding IsEnabled, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Bool2Color}}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}">

The result looked like this:

alt textalt text

The code for the value convertor is below

    public class BoolToColourConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is bool?)
            {
                return new SolidColorBrush((value as bool?).Value ? Colors.Red : Colors.Orange);
            }
            throw new NotImplementedException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
Enough already
though i solved the problem in a different way, this is a workable solution. unfortunately there is no elegant way of solving this particular problem. I'll post my solution when i get a free moment.
Darko Z
We look forward to seeing your alternative ("the more strings to the bow the better the music" as they say). Thanks
Enough already