Stumbling Through

Join me as I stumble, bumble and fumble my way through some new developer technologies. We'll laugh, we'll cry, there may be a mouse tossed through a monitor, but in the end we will all hopefully learn something.
in

Stumbling Through: WPF (Style Part I)

The second series of Stumbling Through WPF is going to focus on something that should be very familiar to any web developer, but has long been missing in windows development (in an integrated fashion):  Style.  Style in WPF has been implemented similarly to CSS for web development, though one could make the case that WPF styles are even more powerful than CSS for a few reasons that we will get into later in this post.  First off, I’d like to discuss the goal of this series.  I ultimately want to create a separate project to house my styles, creating a ‘library of style’ (kinda sounds like a show on the E! channel, not that I’ve ever watched the E! channel of course) that can be consumed by any other WPF application.  I’ve expanded a little bit on the transparent listbox style that was developed in my series of blogs on WPF transparency, and reorganized them into one XAML file called HotTrackListBox.xaml, which looks like this:

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   

    <Style x:Key="HotTrackListBoxStyle" TargetType="{x:Type ListBox}" >

        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>

        <Setter Property="Background" Value="Transparent"/>

        <Setter Property="IsSynchronizedWithCurrentItem" Value="True"/>       

        <Setter Property="ItemContainerStyle" Value="{StaticResource HotTrackListBoxItemStyle}"/>               

        <Style.Resources>

            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />

            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />

        </Style.Resources>             

    </Style>

    <Style x:Key="HotTrackListBoxItemStyle" TargetType="{x:Type ListBoxItem}">

        <Style.Triggers>

            <Trigger Property="IsMouseOver" Value="True">

                <Setter Property="ListBoxItem.BitmapEffect">

                    <Setter.Value>

                        <OuterGlowBitmapEffect GlowColor="AliceBlue" GlowSize="4"/>

                    </Setter.Value>

                </Setter>

            </Trigger>

            <Trigger Property="IsSelected" Value="True">

                <Setter Property="ListBoxItem.BitmapEffect">

                    <Setter.Value>

                        <OuterGlowBitmapEffect GlowColor="AliceBlue" GlowSize="14"/>

                    </Setter.Value>

                </Setter>

            </Trigger>

        </Style.Triggers>       

    </Style>

    <Style TargetType="{x:Type TextBlock}">

        <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ViewportWidth}" />

        <Setter Property="TextWrapping" Value="Wrap"/>

    </Style>

</ResourceDictionary>

 

I’ll do my best to explain each line of this style, but what it does is make a listbox transparent and multi-line (as in the previous transparency blog) and it also lights up the options as the user mouses over them, keeping the current selection brighter than the others. 

Starting with the first node, we see that this entire style is a ‘Resource Dictionary’.  This means that it can be referenced the same as any other dictionary, that is, each item will have a key which is used to retrieve its definition from the dictionary when it is needed.  The usefulness of this will become more clear when we actually attempt to consume this style.

The next two lines, the xmlns lines, define the default namespaces that will be used throughout the style definition.  Hopefully there is nothing new to you here.

Now we are getting into the guts of things with the ‘Style’ tag.  Here, we define values for two attributes:  Key, and TargetType.  Key is how we will reference this style when it is being consumed, it identifies the style uniquely in this dictionary.  TargetType allows us to narrow down what type of controls this style can be applied to.  In this case, we are specifying that only types of ListBox can use this style.

The next four lines are ‘setters’, which simply set properties of the control to the values specified here.  If you’ve followed my previous blogs on transparency, then the first two setters should look familiar, disabling the horizontal scroll bar and making the background transparent by default.  The ‘Is Synchronized with Current Item’ property is something used by databinding and warrants a more detailed explanation , which will occur in future posts.  It is here only because I continually forget to set it for my list boxes and wonder why databinding isn’t working.  The final property setter is telling the style that any list items that appear will have the ‘Hot Track List Item’ style, which oddly enough is defined later in this very dictionary.  Pretty cool that it doesn’t care which order you define things in.  The next section, Style.Resources, should again look familiar from my previous posts on transparency.  This is the part that makes the list selection transparent by overriding the highlight brush and control brush.

Next, we are defining another style with the key of HotTrackListItemStyle that can only be applied to ListBoxItems.  The first section is two triggers, which can set values for list box item properties when certain conditions are met.  In this case, we are capturing the ‘On Mouse Over’ event to set the ‘bitmap effect’ property to a new outer glow bitmap effect.  Note that it is not necessary to turn off the glow in an ‘On Mouse Out’ event, it seems to be smart enough to do that for you.  The second trigger gives the brighter outer glow bitmap effect with the item is selected.  I’m no CSS expert, but this trigger stuff seems like something that, if possible, would be very difficult to implement in a CSS.

Finally, we have our TextBlock style definition that essentially sets all text blocks to wrap based on their parent’s scroll panel, which in this case, is all the text blocks rendering text in our list box.  I feel that this was a bit of a hack, because won’t this style be applied to ALL text boxes, even those not a part of a list box?  Time and testing will tell, but the alternative of defining a content template just blew my newbie mind at this time.

In the next post, I’ll get into creating our ‘Visual Foundation’ project that will house our library of style.  I wanted to call the project ‘Presentation Foundation’, but some jerk already had dibbs on that name.  I’ll also discuss how to reference styles from another project and use them to display our ‘hot track list box’ item defined above in any WPF application.

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required)