Tip For Finding Resources for a Control in generic.xaml

I’ve recently be working on changing the ControlTemplate of a GridViewColumnHeader in a custom ListView that we’ve been working on. (The ListView was rewritten for sorting, so that’s why it had to be custom.)

One of the things we had to do was swap out ControlTemplates so that we could display a caret to indicate ascending or descending lists. We ended up deciding on ControlTemplates over DataTemplates because the DataTemplates would only work for ListViews that had no custom DataTemplates for the headers. We’re doing all sorts of crazy stuff with our headers and we need to preserve our DataTemplates, so this wasn’t an option.

In any case, I was having no luck finding the resource when I named it this way:

<ControlTemplate x:Key="MyCustomControlTemplate" TargetType="{x:Type GridViewColumnHeader}">

I was using the following code to try and find the resource.

ControlTemplate myNewTemplate = (ControlTemplate)Resources["MyCustomTemplate"];

However, we were able to solve the problem by naming the resource this way

<ControlTemplate x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:MyCustomListView}, ResourceId=MyCustomControlTemplate}"
        
TargetType="{x:Type GridViewColumnHeader}">

And then using this code to access it.

ComponentResourceKey myCustomTemplateKey = new ComponentResourceKey(typeof(SortableListView), "MyCustomTemplate");
ControlTemplate myNewTemplate = (ControlTemplate)this.TryFindResource(myCustomTemplateKey);

Just thought I’d pass it along.

How to Assign ColumnHeaderContainerStyle and ColumnHeaderTemplate to a ListView Style

This is just a quick note on creating a ListView style with the appropriate GridView style and template assignments.

Normally, I’ve been creating listviews that look like this:

<ListView x:Name=”MyListView”
               ItemContainerStyle
=”{DynamicResource MyListViewItemContainerStyle}”>
   
<ListView.View>
        
<GridView ColumnHeaderContainerStyle=”{DynamicResource MyListViewHeaderStyle}”
                        
ColumnHeaderTemplate=”{DynamicResource MyGridColumnHeaderTemplate}”> 

I did this because I didn’t know exactly how to assign these styles and templates to the ListView Style. In the style, ColumnHeaderContainerStyle and ColumnHeaderTemplate are not properties of the ListView, they are properties of the GridView… which you can’t create a style for.

Instead, you can encapsulate all the information above in the following style.

<Style x:Key=”CustomListViewStyle” TargetType=”{x:Type ListView}”>
      <
Setter Property=”GridView.ColumnHeaderContainerStyle” Value=”{DynamicResource MyListViewHeaderStyle}” />
     
<Setter Property=”GridView.ColumnHeaderTemplate” Value=”{DynamicResource MyGridColumnHeaderTemplate}” />
     
<Setter Property=”ItemContainerStyle” Value=”{DynamicResource MyListViewItemContainerStyle}” />
</Style>

Problem solved.

Styling the ScrollViewer

I recently got a comment asking if I could do something on creating a Blend-type ScollViewer styling. The only problem is that the ScrollViewer is a multi-post affair, which I’ll try to get completed in the next month or so. I’m going to go ahead and put up the basics here, much like my Styling the ComboBox and Styling the ListView posts.

In the meantime, I’m making available for download a Resource Dictionary with the Blend ScrollViewer style as I’ve approximated it. (You may have to right-click “Save As…” on that file since IE will do its darndest to open it up.) Just load the resource dictionary into your project and set

<ScrollViewer Template=”{DynamicResource BlendScrollTemplate}” />

Note: This is not the “real” Blend styles… just my rendition/approximation.

In the meantime, here’s the overview for the ScrollViewer. When you look at a template of the ScrollViewer (right-click on the ScrollViewer, got to “Edit Control Parts (Template) -> Edit a Copy…“) you should see something like this:

clip_image001[7]

If you want to change something about the main content area (highlighted below), you’re probably going after the PART_ScrollContentPresenter

clip_image001[11]

If you want to style the corner (highlighted below), look at changing the Corner Rectangle.

clip_image001[15]

If you want to style the HorizontalScrollBar and/or the VerticalScrollBar (highlighted below), you should right-click on either the PART_VerticalScrollBar or the PART_HorizontalScrollBar and go to “Edit Control Parts (Template) -> Edit a Copy…

clip_image001[13]

A point of note: Because of the way Blend works, it can be difficult to visually style a Vertical and Horizontal ScrollBar in the same Template. Don’t create another template. It’s a waste of time and will make your resources a pain to navigate. I’ll go over exactly what to do in a little bit.

The ScrollBar template should look something like this:

clip_image001[9]

If you want to style the ScrollBar thumbs (the bars you would drag to scroll, highlighted below), you’ll need to change the template for the “Thumb” in the PART_Track. Note: Unless you’re doing something really complex, you should only need to style the Thumb control one time. You don’t need different styles for the vertical and the horizontal.

clip_image001[17]

If you want to style the directional buttons (highlighted below), you will need to change the templates for the first and last “RepeatButton” controls (the ones that aren’t in the PART_Track) using the right-click -> Edit Control Parts (Template) -> Edit Template. (This template should already be copied into your resources.) Again, unless you’re doing something complex, you should only need to style this button one time.

clip_image001[19]

If you want to style the empty area that allows for fast scrolling, you will need to change the style for the two RepeatButtons in the PART_Track (DecreaseRepeatButton and IncreaseRepeatButton)using the right-click -> Edit Control Parts (Template) -> Edit Template. You should only need to do this one time and then apply that style/template across the all the instances of this button.

clip_image001[21]

Over the next couple weeks, I’ll try to put up posts going over how to style all of these into the Blend style. I’ll update this post pointing to the more in-depth tutorials as I go along. Until I get around to doing that, feel free to download the ResourceDictionary with the Blend styles in them.

Go Get Windows Live Writer

My previous post is the first one that I’ve used Windows Live Writer to create. I changed from the default WordPress blog post composer because Live Writer gives me the following features:

  • I don’t have to upload my images file-by-file… I just use OneNote to screen grab and then copy and paste from OneNote into Live Writer and Live Writer just uploads everything to my site. My posts are pretty image heavy, so I probably saved about 30 minutes of time with this feature alone.
  • The Paste from Visual Studio plug-in lets me… well… paste from Visual Studio and maintain the colors and formatting. You’ll probably see more code integrated into my posts, since I hate putting in code that isn’t color coordinated. Time saved: about 15 minutes
  • I don’t lose my posts to some web or Javascript weirdness. The posts I put up take, on average, 2 hours to create. Losing my work is devastating.
  • Super simple interface. I don’t know what team at Microsoft was working on this, but I wouldn’t be surprised if they took their cues from the OneNote team. Huge Interaction Designer props for harnessing the power of simplicity and elegance. I never have to ask myself how to do something… it is transparent. Now, maybe I’m not trying to do enough complex stuff, but I’m ok with that. Way to design 90% of the audience rather than agonize over that last 10%.

Go get it.

Head First C#: Silverlight Supplement For Chapter 1 (pages 8-16)

Silverlight Concepts Covered:

  • Building a basic Silverlight project
  • Creating code behind for a event triggered by the user
  • Creating an HTML alert (a fake MessageBox) in Silverlight

Project Files are available for download at the bottom of the page.

Because I’m an interaction designer and not a coder, I find that there are certain things that can be very limiting for me. I’ve decided to fix that by learning how to code properly. To do so, I’m using a book that actually makes sense to me: Head First C#. If you’ve never used the Head First series, its generally a pretty good series zero-to-sixty book on the given topic which teaches by doing (the only way I’ve found I can learn anything).

Sadly, Head First C# currently uses WinForms for all user interfaces. This is the beginning of a series in which I’ll go through the book, but replace all the WinForms with Silverlight. I will very purposely not give the rest of the lessons because I have a nagging moral qualm in the back of my mind about taking someone else’s intellectual property and putting it up on my blog. Call me old fashioned.

I will, however, be going through the project and offering alternative code downloads of the projects (with Silverlight interfaces). I figure that, because the Heads First books allow free downloads of their project code on their website, they don’t mind me doing this on mine. If anyone from O’Reilly is reading this and disagrees, just let me know.

The first chapter has you building a program for entering and saving Contacts from start to finish. I will be pointing to the pages and listing alternative Silverlight steps

Pages 8-16

1. Start Visual Studio 2008 and select “Silverlight Application” from your list of options. The default “Web Page” options should be fine for what we’re doing.

clip_image001

2. Open up Expression Blend 2.5 (I’m using the June 2008 Preview) and find your project and open it.

clip_image001[12]

3. Double Click on the Page.xaml file to open it up in Blend. We’re going to create the basics of our user interface here.

4. Go ahead and grab the “Objectville Paper Co” image from the Heads First web site. Right click on your project in Blend and select “Add New Folder”. Name your new folder “Images”. Right click on that folder, click “Add Existing Item…” and navigate the graphic you downloaded. Your project should look something like this:

clip_image001[14]

5. Drag the image from the project to the canvas. Things may look a little crowded on the canvas, so lets make it a little bigger. Click the “Properties” tab (a) on the right side of Blend and make sure you have UserControl (the highest object in the tree) selected in the “Objects and Timeline” (on the left side) (b). Change the Width to 600 and the Height to 800 (c).

(a)

clip_image001[16]

(b)

clip_image001[18]

(c)

clip_image001[20]

6. You’ll probably notice that our images got stretched. We’re going to follow the spirit of HFC# and change it to be an unstretched size. Select the Image from your Objects and Timeline and set Stretch to None, HorizontalAlignment to Left and VerticalAlignment to Right.

clip_image001[22]

clip_image001[24]

7. Before we run the project, let’s change the background so we can tell where our page is. Select the LayoutRoot and change the Background to something not white (I chose a light blue). Save All in Blend and click on your open Visual Studio 2008 and hit F5. (I haven’t had a lot of luck getting Silverlight projects to run from Blend)

OK, that gets us to page 14. The next step is to add extra code to the auto-generated code in Visual Studio.

8. Go back to Blend and click on the Image and go to the Events section (the little lighting icon) of the Properties tab. This will give you a list of all the events available for the Image control.

clip_image001[26]

9. In MouseLeftButtonUp, type the name of the method you want called when the Image registers a MouseLeftButtonUp event (I typed ImageClick) and hit enter.

clip_image001[28]

10. Blend will communicate to Visual Studio, which will in turn auto-generate all the code you need for that event handler. It should look something like this:

private void ImageClick(object sender, MouseButtonEventArgs e)

{

}

11. Type the following at the top of the page:

using System.Windows.Browser;

and then type the following into the ImageClick method:

HtmlPage.Window.Alert(“Contact List 1.0. \nWritten by: Your Name”);

Run your project.

From here, HFC# walks through creating a database. The next installment will pick up after the database is created and we get to bind the data to our interface.

Download Project Files for this post: HFCSharp Part 1 Project Files

Clicking or DoubleClicking on an Item in a ListView

This is little more than a pointer to a fantastic post by Mike over at Mike’s Code Blog, but I figured it was worth passing along. Mike’s post is focused on finding which item was double clicked, while mine is on determining when the double clicking happened on an item at all.

 I’ve recently come up against a problem in which we were attaching a doubleclick event to our listview, only to discover it fires when we did something like click on the scrollbar quickly. Since we only wanted it to fire when we were double clicking on the listview item, we had to come up with some way of figuring out where in the listview the user had clicked.

Mike’s code made it easy… I’m reproducing our permutation of it here:

First, we put our event pointer in the XAML like so:

<ListView MouseDoubleClick=”ListViewDoubleClick”>

Then we put this in the code behind:

protected void ListView_MouseDoubleClick(object sender, RoutedEventArgs e)
{
    
//grab the original element that was doubleclicked on and search from child to parent until
    //you find either a ListViewItem or the top of the tree

    DependencyObject originalSource = (DependencyObject)e.OriginalSource;
   
while ((originalSource != null) && !(originalSource is ListViewItem)) 
     {
          originalSource =
VisualTreeHelper.GetParent(originalSource); 
     }
       //if it didn’t find a ListViewItem anywhere in the hierarch, it’s because the user
      //didn’t click on one. Therefore, if the variable isn’t null, run the code

      if (originalSource != null)
     
{
         //code here
      }
}
 

That’s it!

Designer WPF Update

I apologize for my extended sabbatical here… I’ve recently gotten married, which has thrown a bit of a wrench in my blogging commitment.

I’ll start posting again with some regularity in about three weeks, at which point I will also  start working on my first line-of-business Silverlight project. Until then…

How Do I Make a ListView or a ScrollViewer Left Handed?

Several months back, I was doing some work for a company that was using WPF for a stylus based application. One of the things that they found they needed was a scrollbar that could be used by left handed people who would have to cover the entire screen with their left hand in order to scroll a traditional scroll viewer.

The solution ended up being so easy in WPF that I thought I’d post it here.

I’m in a two-birds-one-stone mood, so we’ll do this for both the listview, which will also cover a more traditional scrollviewer. Let’s start with our ever friendly listview.

NormalListViewAt the very sight of this thing, with a stylus in hand, your average lefty is thinking to him or herself “I wonder if I can do my work upside down?” Let’s show them that we love and accept them just as they are.

The first thing we’re going to do is create a new template for this sucker, so right click on your listview and go to “Edit Control Parts (Template) -> Edit a Copy…

Lefty_EditControlParts

Now we’re looking at the standard listview template. Mine looks like this:

ListViewTemplateLet’s dig right into the ScrollViewer. If you’re doing this from the listview (like I am) then creating a template for the listview has already created a template for the scrollviewer. If you’re starting from a basic scrollviewer, you can pretty much start right here.

For the purposes of making this thing easy to work with in Blend, go ahead and set the HorizontalScrollBarVisibility and VerticalScrollBarVisibility to Visible.

 ScrollBar_Visibility

And then “Edit Control Parts (Template) -> Edit a Copy…” (or “Edit Control Parts (Template) -> Edit Template” if it is available).

We are now looking at the guts of the ScrollViewer Control.

ListView ScrollViewer will look like this:

ListViewScrollTemplateThe normal ScrollViewer will look like this:

 NormalScrollViewer

For our purposes, they’re functionally the same. It is actually a fairly simple control… basically just a Grid panel with the columns and rows set up like so:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”*/>
      <ColumnDefinition Width=”Auto/>
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
      <RowDefinition Height=”*/>
      <RowDefinition Height=”Auto/>
</Grid.RowDefinitions>

The scrollBars are set up so that their visibility is tied to (duh) the visibility that is set on the control. But what this does is it means that when they are collapsed… they Grid reclaims the space that they were taking up.

Now… here’s the hilarious part… in order to make this ScrollViewer left handed, all you have to do is swap the Grid.Columns:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”Auto/>
      <ColumnDefinition Width=”*/>
</Grid.ColumnDefinitions>

You’ve now switched the columns so that the left handed column is auto. Here’s a list of the Grid.Column realignments you’ll need to make:

Change Column to “1″:

Lefty_Column1

  • PART_HorizontalScrollBar
  • All DockPanels (ListView only)
  • PART_ScrollContentPresenter (ScrollViewer only)
  • Corner (ScrollViewer only)

Change Column to “0″:

Lefty_Column0

  • PART_VerticalScrollBar

Basically, swap everything from in the two columns.

Done.

FinalLeftyListViewIf you want to make this a more robust control, I recommend creating a ScrollViewer with an additional dependency property (IsSouthPaw or something). Make it so that your Grid has three columns:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”Auto/>
      <ColumnDefinition Width=”*/>
      <ColumnDefinition Width=”Auto/>

</Grid.ColumnDefinitions>

And then you can just create a trigger that swaps the column placement of your PART_VerticalScrollBar. Such a trigger will look something like this. And by “something”, I mean “exactly”.

<Trigger Property=”IsSouthPawValue=”True>
      <Setter Property=”Grid.ColumnTargetName=”PART_VerticalScrollBar“  Value=”0/>
</Trigger>

Go forth and make Ned Flanders proud.

By the way, I listen to pop punk whenever I write my tutorials and I just thought I should let Senses Fail know that they can probably get away with about 80% less “dying cat” screaming and still put out good music. You know… because they’re probably WPF programmers on the side and they’ll probably read this to solve all their left-handed scrollbar needs.

WPF Designers Guide to Styles And Templates

This is a post that has taken months to complete, but addresses something that I don’t think I’ve seen sufficiently covered for anyone who is new to WPF. Resultantly, we’re going to go through it slowly and I’m officially begging for additional questions at the end.

Part of the problem with styles and templates in WPF stems from the fact that Blend allows a wonderfully simply way of creating a copy of a template:

SNT_EditControlParts

It then gives you something that looks like this:

<Style x:Key=”My_TemplateTargetType=”{x:Type Button}>
      <Setter Property=”Template>
            <Setter.Value>
                  <ControlTemplate TargetType=”{x:Type Button}>
                        <!– blah blah blah –>

So, from a usability point of view… I told it to create a Template and it created a style. I judged from this that styles and templates were roughly the same thing.

And I was confused.

So, first, I’ll try to explain styles and templates by explaining how they work and then I’ll draw an analogy that I hope is helpful.

Let’s say you have a button.

Hi_Button

You can change all sorts of properties of that button… visibility, background, width, height, margins, border thickness, alignment, font, whatever.

If you have a dozen buttons and you want them all to have the same properties, you can create a button style that specifies those properties and assigns them across the board. You can edit a style in Blend by selecting your control, clicking in the menu: “Objects -> Edit Style -> Edit a Copy…“.

Style editing in the objects tab will look like this.

Style_Objects

As you can see, there are no objects in the visual tree to play with… only properties to assign in the properties tab.

Button_Style_Properties

When you assign a property in Blend, your styles will save that assignment as setters and values. Let’s say we wanted all of our buttons to have green 18 point font  bold text. We could create a style that looked like this:

<Style x:Key=”GreenBorderButtonTargetType=”{x:Type Button}>
      <Setter Property=”ForegroundValue=”#FF00FF00/>
      <Setter Property=”FontSizeValue=”18 />
      <Setter Property=”FontWeightValue=”Bold/>
</Style>

The styles can only define properties that belong to the control type that they are styling (which is defined in the “TargetType“). Also, styles can only give information for properties the control already has and only in the way that the control is already set up. For example, because there is no property for changing the corner radius of a button, you can’t change the corner radius of a button using a button style.

However, what if we want to change something about the button that we can’t change with the given properties? For example, let’s say we wanted to see all the text show up twice.

Double_Button

In order to do this, we need to make what I’m going to call “structural changes” to our control. Structural changes are changes in the actual guts of the control, changes to the base elements that make up the control. For this we need a control template.

Boiled down to their essence, templates are little chunks of XAML that are inserted whenever you use your control. When you right click on something and go to  “Edit Control Parts (Template) -> Edit a Copy…“, Blend takes the default XAML that makes up your control and places it in the resources so that you can change it at your whim.

You can get to the Control Template using the right-click method described at the top of this post. Your basic button template will look something like this:

Button_Template

<Style x:Key=”MyButtonStyleTargetType=”{x:Type Button}>
      <Setter Property=”TemplateValue=”{DynamicResource MyButtonTemplate}/>
</Style>

<ControlTemplate x:Key=”MyButtonTemplateTargetType=”{x:Type Button}>
      <Microsoft_Windows_Themes:ButtonChrome x:Name=”Chrome>
            <ContentPresenter />
      </Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>

We can go in and add an additional ContentPresenter in here, like so:

<ControlTemplate x:Key=”MyButtonTemplateTargetType=”{x:Type Button}>
      <Microsoft_Windows_Themes:ButtonChrome x:Name=”Chrome>
            <Grid>
                  <Grid.RowDefinitions>
                        <RowDefinition Height=”.5*/>
                        <RowDefinition Height=”.5*/>
                  <Grid.RowDefinitions>
                  <ContentPresenter Grid.Row=”0/>
                  <ContentPresenter Grid.Row=”1/>
            </Grid>
      </Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>

And now our button shows all the content twice, one right on top of another.

The best way I’ve found to think about it is to think of your control as a car.

The dealer give the buyer a list of things that they can change about the car… interior color, leather or fabric seats, 4 or 6 cylinder engine… these are properties of the car… defined in the car “style”. (Basically, you can think of everything that you’re allowed to tweak at this website as the style of the car.)

<Style x:Name=”MySpecialCarTargetType=”{x:Type Camry}>
      <Setter Property=”ExteriorColorValue=”Blue/>
      <Setter Property=”TransmissionTypeValue=”5SpeedManual/>
</Style>

Camery_Basic
 
But let’s say that the buyer doesn’t want a normal seat… she wants a big comfy chair in place of the regular drivers seat. This is something outside of the scope of the list of things she was allowed to choose from, so they have to draw up new blueprints for making this new car. They have to create a new car “template”.

If our normal Camry blueprint looks like this:

<ControlTemplate x:Key=”MySpecialCarBlueprintTargetType=”{x:Type Camry}>
      <CamryFrame x:Name=”CamryFrame>
            <Seat Type=”Drivers/>
            <Seat Type=”FrontPassenger/>
            <Seat Type=”BackBench/>
      </CamryFrame>
</ControlTemplate>

We can go in and replace :

<Seat Type=”Drivers/>

With

<Seat Type=”ComfyChair/>

ComfyChair

You may also notice that, with this model we could get rid of all the other seats except the drivers seat or we could add 12 new rows of seats. We can change anything about the car because we’re down into the original car blueprint.

This is the basic difference between styles and templates.

  • A style is a list of properties that can be assigned in bulk to a control.
  • A template goes a big step further and actually defines the underlying structure of the control.

You may be asking: “So how do these two work together? And what is this Data Template think I keep hearing about?”

Given that this post is getting dangerously long already, I’m going to address those issues in a couple more posts on styles and templates.

I’ll end on this note: if you are working in WPF and you’re having trouble with styles and templates, please read all of these posts (as I get to them) and ask questions in the comments section. I’m pretty good about getting to the comments questions and if the question is big enough, I’ll write a whole post on it. There are few things more vital to a WPF developer/designer than to have a firm grasp on styles and templates. It is in this understanding that the power of WPF really comes out.

  • Who’s The Boss? Property Priority in Styles and Templates (coming soon)
  • Create Conditional Styles and Templates (With the Magic of Triggers) (coming soon)
  • So How Do Data Templates Fit Into All This? (coming soon)

Styling the ComboBox Dropdown (popup)

 This tutorial derives from the general “How to Style the ComboBox” set of tutorials.

First let’s make sure you’re in the right place. In this tutorial, we’re going to style the comboBox drop down (also known as the ComboBox popup) seen highlighted in red below.

CB_Image_1

We will not be styling the items inside the dropdown (highlighted in blue). You can learn how to do that here.

So… let’s just go after some of the basics in styling the dropdown. We’ll give it a new background, a new border and we’ll round the edges to make it just a little more bubbly.

To start out, we’ll need to get to our comboBox control template, so right click on the comboBox in the Objects and Timeline window and go to “Edit Control Parts (Template) -> Edit a Copy…

CB_Image_2

Name it something you like and we’re on our way. 

We’ll be editing the PART_Popup. Whatever you do, don’t change the name to this sucker. Whenever you see a “PART_Something”, it is a necessary part of that specific control (hence the naming convention).

The ComboBox dropdown (which we’ll be calling a popup for the remainder of this post)  is made up of a low cost drop shadow (see more on that here), a border, a scrollviewer and the itemsPresenter.

CB_Image_3

Most of the standard styling we might want to do is probably going to happen in the Border titled DropDownBorder. We can alter the background and the border brushes easily enough by just changing them in the Properties window. But you may notice some quirky behavior from our scrollviewer when we change the CornerRadius. Below, I’ve changed the CornerRadius to “0,0,10,10” and we can see that we lose part of the corner under the scrollviewer.

CB_Image_4

CB_Image_5

We can solve this easily enough by adding some padding through the Border. Below I’ve added a padding of “0,0,2,6“.

CB_Image_6

Better, but not really ideal. In a perfect world, we would be able to say that the border us able to cut off its content in that nice pretty rounded manner.  (If anyone knows how to do that… let me know, I haven’t given it hours of thought yet, but I’d love to know). In this case, however, this sub-optimization is the price we’re going to have to pay if we don’t want to have to go in and mess with the scrollbar style and template.