Posts Tagged Implicit Style

How to gray the text of a disabled Silverlight Label control.

Have you ever written code that both offended and impressed you at the same time? Maybe it was a piece of code that flew in the face of accepted design or coding practice yet produced inarguably good results. Maybe you came up with a hack to work around some limitation in your toolset or existing application which proved to be so resourceful you couldn’t help but be proud. I recently had one such moment while working on a Silverlight application.

While trying to design a configuration style dialog using a natural text pattern, I found myself needing to enable and disable blocks of text along with related controls. When disabled, I wanted the control to render itself in a ghosted fashion with grayed out text. The first issue you will run into when doing this in Silverlight is that the TextBlock element can’t be enabled or disabled as it does not derive from System.Windows.Controls.Control and therefore does not have an IsEnabled property.

This is where the Silverlight Toolkit’s Label control comes in as it does derive from Control. Additionally, since the Label control is also a ContentControl, it’s able to host any number of other controls as part of its content template including simple text. The IsEnabled property of a label will properly propagate down to other such controls which inherit from Control thus disabling them as well. However there seems to be a known issue with the current version where simple text content in the control is not rendered with the same disabled/ghosted style as the other controls. The net affect was that a Label was no different than a TextBlock for my purposes.

Starting in Silverlight 4, through the use of implicit styles, you can now define the look and feel of a control without having to specify a key name. This allows you to target your style for a specific type of control without having to specifically add a reference to the style in the location where you make use of the target control type. You can read more about Implicit Styles in Silverlight 4 at SilverlightShow.net.

This is the part where a hack becomes a thing of beauty (or at least power anyway). Leveraging some XAML provided in the CodePlex ticket for this issue and tweaking it for inclusion in App.xaml as an Implicit Style, I was able to extend all my label controls in the application with a grayed out text feature when they are in the disabled state. So while I was a little dismayed that something as simple graying out some text for a disabled control required a hack, I was also quite impressed with the power of Implicit Styles.

Sample App.xaml code:

<!-- /////////////////////////////////////////////////////////////////////////////
SDK LABEL HACK: the sdk version of the label doesn"t gray the text when disabled. 
http://silverlight.codeplex.com/workitem/969
-->
<style targettype="sdk:Label">
  <setter property="IsTabStop"
      value="False" />
  <setter property="HorizontalContentAlignment"
      value="Left" />
  <setter property="Template">
    <setter.value>
      <controltemplate targettype="sdk:Label">
        <grid>
          <vsm:visualstatemanager.visualstategroups>
            <vsm:visualstategroup x:name="CommonStates">
              <vsm:visualstate x:name="Normal" />
              <!-- add state change when Disabled-->
              <vsm:visualstate x:name="Disabled">
                <storyboard>
                  <objectanimationusingkeyframes storyboard.targetname="ContentControl"
                                   storyboard.targetproperty="Foreground"
                                   duration="0:0:1.5">
                    <discreteobjectkeyframe keytime="0">
                      <discreteobjectkeyframe.value>
                        <solidcolorbrush color="Gray" />
                      </discreteobjectkeyframe.value>
                    </discreteobjectkeyframe>
                  </objectanimationusingkeyframes>
                </storyboard>
              </vsm:visualstate>
            </vsm:visualstategroup>
          </vsm:visualstatemanager.visualstategroups>
          <border background="{TemplateBinding Background}"
              borderbrush="{TemplateBinding BorderBrush}"
              borderthickness="{TemplateBinding BorderThickness}"
              padding="{TemplateBinding Padding}"
              cornerradius="2">
            <contentcontrol x:name="ContentControl"
                    foreground="{TemplateBinding Foreground}"
                    content="{TemplateBinding Content}"
                    contenttemplate="{TemplateBinding ContentTemplate}"
                    fontweight="{TemplateBinding FontWeight}"
                    cursor="{TemplateBinding Cursor}"
                    horizontalalignment="{TemplateBinding HorizontalAlignment}"
                    horizontalcontentalignment="{TemplateBinding HorizontalContentAlignment}"
                    fontfamily="{TemplateBinding FontFamily}"
                    fontsize="{TemplateBinding FontSize}"
                    fontstretch="{TemplateBinding FontStretch}"
                    verticalalignment="{TemplateBinding VerticalAlignment}"
                    verticalcontentalignment="{TemplateBinding VerticalContentAlignment}"
                    istabstop="False" />
          </border>
        </grid>
      </controltemplate>
    </setter.value>
  </setter>
</style>
<!-- END SDK LABEL HACK
///////////////////////////////////////////////////////////////////////////// -->

, , , ,

Leave a comment

%d bloggers like this: