DISCLAIMER: I write this post more for myself because I tend to forget how to do things. There can very well be other proper ways of doing this, but this is the “good enough” solution, at least for me.
I was playing around with WPF again since it’s been a while. I wanted to customize the scrollbar and I found it was quite a task. I finally figured out a simple way of doing it.
The look I wanted was a simple, thin, vertical bar (I guess you could do the same with the horizontal bar.
1. So we start with a ScrollViewer that contains a RichTextBox(or whatever you want)
2. Now we proceed to EditTemplate –> Edit a Copy.
3. You’re probably already familiar with this dialog box. Give your template a Name when you click okay, by default, it’ll add this to your window’s xaml. But if you want to later on reuse this template, choose the option to define it in a Resource dictionary. Later on, all you’ll have to do is add that resource dictionary to your project and you’ll be able to apply the style to your ScrollViewer.
4. We’ll fix the VerticalScrollBar in this sample but you can very well do the same for HorizontalScrollBar. To start, right-click on PART_VerticalScrollBar and click on EditTemplate –> Edit a Copy. Again, you’ll be asked to select a name and where you want to save this style. This time, we’re editing the ScrollBar component (previously was the entire ScrollViewer).
5. If you expand the template that you’re presented with, you’ll see the elements below. In my case, I want to delete the two RepeatButtons since clicking anywhere above and below the Thumb more or less does the same thing.
5a. But lets say you wanted to edit the buttons, what we do, is draw out what we want the button to look like anywhere on the canvas. We’ll delete this later on. Here, we have a Grid that contains our desired button template.
5b. What we’ll do now is right-click on the grid and select Make Into Control. A dialog box will appear that will ask you to select which control you want this grid to magically turn into. You’ll notice above that the buttons for scrolling up and down are RepeatButtons, so we can type into the search box to find the component, click to select and we’ll name it into something we will recognize later on, in my case, ScrollUpButton.
5c. Now we’re editing the RepeatButton template. We can go ahead and delete the automatically generated ContentPresenter since we don’t need any content in our template.
5d. You’ll notice that you can also go into the states tab to edit the look of your button on different states.
5e. Once you’re done editing, you can go back to the Objects and Timeline tab and click on this button that will take you back to the ScrollbarTemplate
5f. Now to apply the style, select the first RepeatButton –> Edit Template –> Apply Resource –> ScrollUpButton (or whatever you named your template)
5g. You’ll now see the button with the style you’ve defined. Now remember to delete that Grid turned Repeat button that we used to create the style or else, it’ll become part of your template/application
6. Like I said, I’m deleting my up and down buttons because I don’t want them. You’ll notice that the grid this ScrollBar was defined in has Rows that hold the buttons and the thumb / track. I’ll need to delete the extra rows since I don’t need them now and I want the thumb and vertical bar to occupy the entire height. I tried deleting this through the designer but it only wreaked havoc (might be a user error) but I found the safest way to do this is to delete from the XAML code. Click on this button in the upper right corner of your design canvas to show the xaml editor. (Now you know why I said XAML typing instead of XAML editing)
7. What I’ll do now is delete the 1st and 3rd row definitions.
8. Now I’ll see my scrollbar occupy the full height.
9. Next, I want to change the look of the ScrollBar’s thumb. You’ll see that the type of component this is is a Thumb. So we can do as we did with the Repeat button to style this. Make into Control only works on single objects so if you have several objects you want to include in your template, just right-click –> Group Into –> Grid to make them one.
10. Now you can follow the steps in 5b but this time, instead of RepeatButton, we select Thumb in the Make Into Control dialog.
11. Now continue with 5f to go back to ScrollBar template editing and apply the template to the Thumb object. You’ll now see our ScrollBar has changed. Again, remember to delete that extra thumb that we used to create the style.
12. One last thing. Maybe you don’t want your ScrollBar to be as thick as this. So using the button in 5e, go back up to the ScrollViewer template. With the PART_VerticalScrollBar selected, go to the Properties tab and scroll down to the Style property. You’ll see that it’s highlighted in green which means it’s being bound to a local resource.
13. Click on Edit Resource
14. You’ll then see our style, and if with it selected, you scroll down the Properties tab to the Width property, again you’ll see that the Width property is bound.
15. Click on the Advanced Options button (that little square) and select Reset. You should then be able to put in whatever width you want.
16. Now when you click on the button in 5e. (Return scope button) it actually takes you to the topmost level which is the window. So you’ll have to do an Edit Template… on the ScrollViewer again to edit the ScrollViewerTemplate. (By the way, I’ve edited my Thumb template to make it look alright with a Width of 5, i.e., change the width of the topmost grid in the template to 5 and fixed the components inside to make it look good).
You’ll notice that the second column in the grid is set to auto-sized so you’ll want to click on that icon till it says pixel sized (locked lock)
17. With the handle selected (that inverted triangle there) you can now set the width property to what fits your template.
Now if you return scope to window, (5e), and run your app, you’ll now see your fully functional and newly styled ScrollViewer.
hmm.. looks like there’s one more property you need to set. With the PART_VerticalScrollbar selected, set the Background property to No brush.
This is the effect you will get. Note, I’ve also set the RichTextBox borders to zero to remove all borders.
And that’s it!