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.
At 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…”
Now we’re looking at the standard listview template. Mine looks like this:
Let’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.
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:
The normal ScrollViewer will look like this:
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”:
- PART_HorizontalScrollBar
- All DockPanels (ListView only)
- PART_ScrollContentPresenter (ScrollViewer only)
- Corner (ScrollViewer only)
Change Column to “0”:
- PART_VerticalScrollBar
Basically, swap everything from in the two columns.
Done.
If 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=”IsSouthPaw” Value=”True“>
<Setter Property=”Grid.Column” TargetName=”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.
0 Responses to How Do I Make a ListView or a ScrollViewer Left Handed?
Thanks for the Post.
If I wanted to make the vertical scrollbar of a datagrid to be on the left,what controls (instead of Dock Panels) would have to use to set the column to 1?
How to create Mac Style scrollbar in WPF?
indefromoz:
1. Yes. When you go into the template for the ScrollViewer, click above the grid to add another column (so that you have three). Then highlight the column (by clicking in the middle), reset the MinWidth and give it an “Auto” width in the dropdown. I love Blend and use it all the time, but just typing the XAML is easier to me 🙂
2. I can definitely reskin the scrollviewer. I’ll get right on it and post something in the near future. (I’ll e-mail you when it is up)
Hi Matthias,
Your blog post was the only resource that pointed me to a way with which I could align the scrollviewer of a listbox I have been using to the left side of the listbox. Couple of things –
1. When you swapped the width of the columns of the grid, you had to edit the XAML manually. Is there a way to do it within Blend using the “Properties” section?
2. Do you have any plans to do a blog post on “skinning” the scrollviewer control like it appears in Blend itself (and Kaxaml)? Are there any resources I could possibly use as a tutorial?
Thanks a lot for sharing your knowledge and expertise on WPF!
Cheers,
indyfromoz.
Once you set your index, type the following:
MyListView.ScrollIntoView(MyListView.SelectedItem);
I am hoping you can help me with a small problem, it is the only issue preventing me from convincing my boss to allow me to use WPF instead of WinForms.
I am using a
to show a grid of data. When I press Cursor Down the next row is selected as expected, when I scroll down past the lowest visible item the grid scrolls. However, when I set SelectedIndex via code I notice that the item selected is not brought into view.
ListView.SelectedIndex++;
Do you know how I can set the current row via code and have it made visible (preferably in the vertical centre of the grid, but just visible would be sufficient!).
Thankyou very much for your time!
Pete