Posts tagged ‘WPF’

Create A Snapping Slider In Blend Using Behaviors (Silverlight 3 or WPF)

UPDATE: It turns out that in WPF, there is an easier way to snap the slider. For integers, simply check the “IsSnapToTickEnabled” and set your TickFrequency accordingly. Which means that this behavior is really only useful for Silverlight, which doesn’t have those properties.

Behaviors are easily the coolest thing that has ever happened to anything.

Perhaps I overstate my case somewhat. But they’re still pretty cool.

To me, a wonderful example is the ability to let designers/developers get some really cool functionality out of the Silverlight or WPF slider.

Now, one might normally think that there is a simple way to make your slider values to snap to an integer or to some incremental number (perhaps base 2 or base 10). Alas, one would be wrong. There have been a couple solutions to this problem (see here and here), but they usually involve creating a new slider subclass with the additional functionality if you really want the interaction to be reusable.

However, behaviors makes all this unnecessary. What is even better is that there is no code difference between WPF and Silverlight on this one. That’s right… this tutorial and the code that goes with it works exactly the same in Silverlight as it does in WPF.

SnappingSlider Behavior (SnappingSlider.cs) – Works for Silverlight and WPF

WPF SnappingSlider Behavior (All Project Files)

Silverlight SnappingSlider Behavior (All Project Files)

You can also download the behavior here (just the cs file) which would make me happy because it ups my street cred among the Silverlight homies (says the whitest man on earth).

If you want to learn how to create it yourself, let’s get started.

In your project in Blend, right-click on the project and go to “Add New Item…”

clip_image001[4]

Choose “Behavior” from the list and type in the name of the behavior you want to create

clip_image001[6]

This is where Blend is way cooler than Visual Studio… it gives you pretty much all the code and imports all the appropriate references for creating a behavior. So, first change the behavior associated object type to a Slider:

public class SnappingSlider : Behavior<Slider>

And go into the inside the OnAttached method, enter the following code:

AssociatedObject.ValueChanged +=new System.Windows.RoutedPropertyChangedEventHandler<double>(AssociatedObject_ValueChanged);

Hint to Code Newbies: If you get to the “+=” part and hit the Tab key twice it will add the necessary code.

Inside the AssociatedObject_ValueChanged method, I added the following code:

private voidAssociatedObject_ValueChanged(objectsender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
{
  
//Let the slider be equal to the Maximum and Minimum values
  
if((e.NewValue != AssociatedObject.Maximum) && (e.NewValue != AssociatedObject.Minimum))
    {
      
//Using the Minimum value as a starting point, only allow values that are
        //   a multiple of the SmallChange value. If you want to simply round to
        //   integers, set it so that:
        //   SmallChange = 1
      
doublecalcValue = Math.Floor((e.NewValue – AssociatedObject.Minimum) / AssociatedObject.SmallChange);
        calcValue = (calcValue * AssociatedObject.SmallChange) + AssociatedObject.Minimum;
        AssociatedObject.Value = Math.Round(calcValue);
    }
   
else
   
{
       
//Sometimes it hiccups on me, so I used this to catch those
       
AssociatedObject.Value = Math.Round(e.NewValue);
    }
}

Once you have that code in place, build the project (menu option Project –> Build Project).

Now you should have the behavior available in the “Assets” tab under “Behaviors” (at the bottom of the picture below).

clip_image001[8]

 

Just drag it onto your Slider and set the Minimum, Maximum and SmallChange properties appropriately. Remember that SmallChange is the value is that is acting as your increment controller.

Creating a Programmatic Path in Silverlight (or WPF)

Download Project Files for Creating a Programmatic Path in Silverlight or WPF

(Note: The project is in Silverlight, but if you copy and paste the code into a WPF project, it should work without any changes)

Have you ever wanted to create a Path programmatically or create a Path in code behind or dynamically build a Path or hand code a Path in Silverlight or WPF?

Yes, I just said the same thing 4 different ways, but I’m trying to cast a wide net for Google to catch. One of the biggest troubles I have when I’m trying to do something new is that I don’t always know the proper terminology, so I try to think of all the ways people might want to ask the question.

I’ve been playing around with a good number of information visualization concepts recently and one thing that I’ve found that I needed was the ability to create a path programmatically.

One way to do that is to tackle and fully grok the Path data code system. (Good guides to it are here and here.) This system is really cool, but (unless I’ve missed something) they cannot be animated.

I wanted to build a path based off a data set, but that means that I have to build it programmatically. I didn’t find a lot of useful stuff on how to do this, so I thought I’d throw some out there.

First, because I’m a XAML guy, I’m going to provide a simple XAML example of a Path that can be animated:

<Path x:Name="MyPath" Fill="#FFA30000" Stroke="Black" Width="100" Height="100">
    <
Path.Data>
        <
PathGeometry FillRule="EvenOdd">
            <
PathFigure IsClosed="True" StartPoint="0,0">
                <
LineSegment Point="0,100"/>
                <
LineSegment Point="100,100"/>
                <
LineSegment Point="100,0"/>
            </
PathFigure>
        </
PathGeometry>
    </
Path.Data>
</
Path>

This path is a simple square and looks like this:

clip_image001

Now, let’s assume you want to recreate this programmatically using a collection of points that represent X,Y coordinates. If you’re using an ObservableCollection of Points (like I am) you can use the following method to return an the appropriate path.

Path createPath(ObservableCollection<Point> rawData)
{

    Path FinalPath = new Path();
    PathGeometry FinalPathGeometry = new PathGeometry();
    PathFigure PrimaryFigure = new PathFigure();

    //if you want the path to be a shape, you want to close the PathFigure
    //   that makes up the Path. If you want it to simply by a line, set
    //   PrimaryFigure.IsClosed = false;
   
PrimaryFigure.IsClosed = true;
   
    PrimaryFigure.StartPoint = rawData[0];

    PathSegmentCollection LineSegmentCollection = new PathSegmentCollection();

    for (int i = 1; i < rawData.Count; i++)
    {
        LineSegment newSegment = new LineSegment();
        newSegment.Point = rawData[i];
        LineSegmentCollection.Add(newSegment);
    }

    PrimaryFigure.Segments = LineSegmentCollection;
    FinalPathGeometry.Figures.Add(PrimaryFigure);
    FinalPath.Data = FinalPathGeometry;

    return FinalPath;
}

Once you have the path in place, you can just add it to your layout and it should show up. If you’re still confused, you can download the project that I created this in and walk through the rest of it yourself.

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.

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.

Wii + WPF = Multipoint UX

We’re at MIX08 in Las Vegas this week, and presenting in a few sessions.  If you’re here, come check out Matthias Shapiro and Galen Murdock’s Wii + WPF = Multipoint demo in Marcello 4403 on the 4th floor.  We’re in Open Space #3 from 11:30am-1:00pm. 

Apparently our posting on the bulletin board has garnered quite a bit of attention.  Come join the fun, play with the app, and see how we built it!

Check out the background of the project at Matthias’ blog at www.designerwpf.com

~ galen

Special Leap Day Link-O-Rama

My brain is out of town while I’m working on our MIX Show Off Entry. In the meantime, I need to post some links so that I don’t forget them. I suppose you can use them too, if you want:

You’ll notice that there is a little bit of focus on Silverlight 2.0 here… That’s because it’s awesome. Keep watching, I’ll start blogging on it as I get into it more and more.

How Do I Style The ComboBox Items?

This is actually a continuation of my post on getting the ComboBox items to accept text wrapping, so I’ll be working from that point forward. If you’re coming fresh into this, you won’t be missing anything… but that is my explaination for the pictures containing wrapping text.

When last we left our heroes, we has a couple problems. The first was that our items were either black text on a white background and ran together in a very un-designer-y way.

BeginningViewComboStyling

The second was that the selected item background makes your eyes bleed such a horrid blue color you’ll feel like Paul Atreides staring at a stone burner.

Was that a little too geek? My apologies.

Continue reading ‘How Do I Style The ComboBox Items?’ »

The WPF Designers Guide to Styling The ComboBox

 The ComboBox is not the most complex of the WPF applications, but it can be a little tricky, so lets do a general overview post of it before we go into the specifics of how we’re going to make it work.

First of all, if you’re going to test your comboBox design, you should have it hooked up to an ItemsSource. Don’t have one? I have a tutorial in which I walk through attaching an RSS feed to your control. It was originally written for the ListView, but it will work fine for a ComboBox.

To start out… this is your standard ComboBox:

unalteredComboBox

When working on a comboBox, you have a couple of options for the Items inside the ComboBox. If the options never change and are not data-driven, you can just toss come ComboBoxItems into it. Otherwise, you can connect it to some kind of ItemsSource (see the link above).

All of my examples are done with a data-driven ComboBoxes, but you should get the desired results if you run through the tutorials with ComboBoxItems.

First, a little bit about the structure of the comboBox.

Continue reading ‘The WPF Designers Guide to Styling The ComboBox’ »

Using WPF Binding For A Huge Performance Boost

(I’m getting to the point in a roundabout way… you can skip directly to the point below if you want.)

When I started working on my WPF-Wii tutorials, my first Wii project was the initial version of the WPF-Wii Visualizer.

However, I quickly got tired of writing the code for handling events and transferring the data from the Wiimote library to my application. So (like any noble geek would do) I wrote even MORE code to solve the problem, not only for myself, but for generations to come.

I’ve spend the last week writing a Wii-To-WPF library that shovels the Wiimote properties into properties that use the INotifyPropertyChanged WPF interface. This will allow anyone to connect to the Wii through the WPF data binding. It’s super cool.

(A point of note, I posted an early version of this library. Ignore it. I’m putting up a much improved version in the next couple days.)

The Point

But I had no idea how moving from a basic data transference and event handling to the INotifyPropertyChanged interface would affect my performance.

Here are some screenshots of Perforator (a WPF performance monitoring application) monitoring my WPF-Wii Visualizer in its code-heavy iteration:

non_Data_Binding_Performance

I don’t know what all those numbers mean, but the one I’m interested in is the frame rate. As a designer, smoother motion is good… especially if I’m trying to design a multi-point application. A frame rate of 27 isn’t too bad, but this is the best I got. The frame rate usually hovered around 20, dipping as low as five.

Now… this is what I got when I was binding the data through the XAML (absolutely no code whatsoever):

Data_Binding_Performance

And this was the worst I got. My frame rate was always in the mid 60s and would spike up to 80. Take note that I’m not changing the interface at all. In fact, I’m running the binding version at a handicap (it’s tracking four infrared points instead of the original two).

Exact same XAML … except that the XAML properties are data bound from within the XAML and not assigned via the C# code.

So, lets take an account of the WPF INotifyPropertyChanged interface:

  • Allows DataBinding
  • Permits code-light or code-free interface design
  • Drastic improvements to performance

Use it!

Enough said.

WPF Multi-Point Tutorials, Part 1.5: WPF Visualization of Wii Data

Download WPF Wii Data Visualizer (App only, 355K)
Download WPF Wii Data Visualizer (Visual Studio 2008 Source, 676K)

Warning: The project will not run if your Wii controller isn’t connected to your computer.

Using the WPF Wii Data Visualizer (Video)

OK, now that we’ve gotten our Wii Controllers all hooked up to our computers, it’s time to take a look at the data we’re getting from it.

Over the weekend, I pieced together a little application that will help us visualize the incoming Wiimote data in a way that would help understand the raw data points a little better as well as help out as we head toward our ultimate goal of multi-point WPF application development. This is what I came up with.

WPFWiiDataVisualizer

Disclaimer: The source code at this point is a mess. While the interface is all done in XAML and is very WPF, the code-behind is a hacked together mish-mash. I will at some point go back and restructure the code-behind to take advantage of the INotifyPropertyChanged interface. When I do that, I’ll post on it and we’ll see another example of why WPF is so freaking cool.