Win a copy of Spring in Action (5th edition) this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

How can I make a WPF button appearance change when pressed?  RSS feed

 
Bartender
Posts: 1464
32
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The old(er) Windows Forms buttons provided definite visual feedback when "pressed" (that is, when clicked with a mouse). Here's how a Forms button looked when enabled and the mouse wasn't over it:

[img]http://exlumina.com/formsButton.png[/img]

And here's how it looked when you hovered over it with the mouse:

[img]http://exlumina.com/formsButtonHover.png[/img]

Finally, here's how it looked when you clicked and held the mouse button down:

[img]http://exlumina.com/formsButtonPressed.png[/img]

Those last two aren't exactly as different as black and white, but the user does see an unmistakable change in appearance when a Windows Forms button is actually pressed.

Now compare the images above to the same three contexts applied to a Windows Presentation Foundation ("WPF") Button. Starting with enabled and not being hovered over:

[img]http://exlumina.com/WPFButton.png[/img]

Here it is with the mouse hovering over it:

[img]http://exlumina.com/WPFButtonHover.png[/img]

And here it is being pressed:

[img]http://exlumina.com/WPFButtonPressed.png[/img]

If you think you see a very, very slight difference in appearance between those last two, you're right. The pale blue background of the "hovering" Button is this mix of red, green, and blue: 0xC4E5F6 (or, Red = 196, Green = 229, Blue = 246, on the 0-to-255 integer range of RGB values). The pale blue background of the "pressed" Button is [i]this[/i] mix: 0xBEE6FD (or, Red = 190, Green = 230, Blue = 253). That's a difference so slight, one might wonder why Microsoft bothered to change it at all. In fact, if you look very closely, you will see the single-pixel border also changes a wee bit, from 0x3C7FB1 to 0x2C628B, a slightly bigger change, but still hard to see.

How to make the change more significant?

This is where it all goes nuts... Microsoft appears not to be using the Model/View/Controller approach that Java Swing controls use. Instead, they use a baffling mix of three things: object properties, styles (vaguely like CSS), and templates. The last two are expressed in "XAML," Microsoft's XML-based eXtensible Application Markup Language (and pronounced ZAM-el). I'm not yet fully educated on what the difference between a style and a template is, but I do know you use a combination of the two to render a much more noticeable change when a WPF Button is pressed. Also, although it will seem somewhat grotesque, it is easy to do.

Start with a right-click on the button in the designer, and pick "Edit Template / Edit a Copy..."

[img]http://exlumina.com/editACopy.png[/img]

In the dialog box that appears, select "Apply to all," and "Application." (Note that, although you chose "Edit Template," from the menu, the dialog box is titled, "Create Style Resource." This will not be the last time you find templates and styles weaving in and out of each other.)

[img]http://exlumina.com/createStyleResource.png[/img]

Then click "OK."

What happens next may astound and also disgust you.

In the file, "Application.xaml," you will find dozens of lines of XAML code resembling this: [code=xml] [/code]

If you look at Lines 19 and 21, you may recognize something: the Color attributes match what we observed as the "hovered" and "pressed" colors of the WPF Button (those leading "FF" values are transparency settings, where FF is full opacity). We can change the "pressed" value to something dramatic, like full red, with "#FFFF0000." If we do, run the program, and press the button, here's how it looks:

[img]http://exlumina.com/WPFButtonPressedRed.png[/img]

Yow! That really [i]did[/i] change the look of the pressed button. Well, that's what we were after, so I guess that's progress. Now, because we told the IDE we wanted this to affect all buttons in the application, we should be able to create another button and not have to go through all this work again. Let's try it by adding a second button to this window (which the Visual Studio IDE calls a "document," by the way).

[b]NOTE: There appears to be a bug in Visual Studio (both VS2015 and VS2017RC) that will corrupt your program when you add a second button unless you close and reopen Visual Studio first. The effect can be seen in the Application.xaml file. You can copy the file elsewhere and restore it after it becomes corrupted as an alternative to closing and reopening VS. [/b]

Here's what happens when we do that and run it:

[img]http://exlumina.com/WPFButton2PressedRed.png[/img]

So, it appears we did make a change that, as intended, applies to all WPF Buttons in the application. Indeed, if you create an entirely new WPF window and add a Button to it, then add the code in the Click event for one of the Buttons in the window above to create and show your new window, you will see that the background of that Button also changes to red when it is pressed.

Next post, I'll show how you can use XAML to give a WPF Button that delightful old, early Windows effect of moving a bit when it is pressed.
 
Bartender
Posts: 9493
184
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cool, thanks Stevens!

XAML is the main reason I have not strayed from old Windows Forms applications yet. I think Visual Studio's Forms designer is also much friendlier than the WPF designer. When I eventually have to bite the bullet, I'll come back to these posts.

I also still need to get into JavaFX, after being intimately familiar with Swing. I really dislike having to learn all these new presentation layer technologies.
 
Stevens Miller
Bartender
Posts: 1464
32
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Cool, thanks Stevens!


You're most welcome, and thanks for being one of this new forum's first reader/commenters.

XAML is the main reason I have not strayed from old Windows Forms applications yet.


It certainly is daunting. Microsoft's documentation praises it for making so many things "easy," including: isolating UI design from business logic implementation; decoupling form from function in the various controls themselves; simplifying the creation of custom controls; and (for some reason) further streamlining the use of controls by subdividing the structural and cosmetic portions of a control into, respectively, styles and templates.

All of which I am presently thinking is a lot of nonsese. The very idea that I should have to learn yet another cryptic XML-based, CSS-like "language," just so I can set a color, is mind-boggling. Fact is, I wouldn't be digging into XAML at all, this early into my Visual Basic investigations,were it not for the point of this post: the out-of-the-box implementation of a WPF Button fails to do the most basic thing a GUI button should always do, which is change appearance when pressed. I quite hope that someone who knows why Microsoft thought changing it from a pale, ashen, light sky blue to a pale, ashen, light robin's-egg blue was a good idea will find this post and share what they know.

I think Visual Studio's Forms designer is also much friendlier than the WPF designer. When I eventually have to bite the bullet, I'll come back to these posts.


This is also something that seems to have gone through some evolution. Visual Studio includes a designer and it does work. But you can also open your UI files in "Blend," which used to be known as "Expression Blend," and maybe by a few other names. Some people say this is more powerful, while others say all it does is keep the developer stuff out of the UI designer's field of view. I've tried Blend and, honestly, it all looks a lot like Visual Studio, just with the furniture rearranged.

I also still need to get into JavaFX, after being intimately familiar with Swing.


I've tried to start down that path a couple of times, but it seems very opaque. And I do love Swing. Once you get the hang of its MVC/PLAF architecture, it can do quite a bit for you. Alas, one thing it does not do is react to touchscreens very well. For whatever reason, when you click on a JButton with a mouse, you get the MouseDown event immediately, and can react to it if you want to (before the MouseClicked event is sent). But, with a touchscreen, you don't get a MouseDown event until either you release the button, or move the cursor on it. I believe this is also the case with buttons under Windows Forms. But, with WPF, you can set the Button so that its "click" even is sent upon a mouse-down, which is exactly what you want for a touchscreen. I've tried it and it works well. (I'll do a post on it.)

I really dislike having to learn all these new presentation layer technologies.


Brother, I feel your pain. And it always seems like, no matter which one you think you should be learning, there are plenty of folks who will tell you your choice is dead. Indeed, even though WPF appears to be the latest framework from Microsoft for desktops, I found an article on a panel discussion with some MS developers who said nothing new was likely to be added to it (and that was in 2014!).

I guess part of the problem is that most new work is being done for Web clients, so it's all about JavaScript, CSS, and so forth. The "GUI" is the browser, these days. But people do still develop desktop apps, so we do still need UI platforms for them.

I also have a theory that Microsoft (among others) never likes to let anything they develop get too old, for fear that competitors will use relatively recent advances in design, hardware, method, etc. to offer superior alternatives. It does seem like, just about every time I dig into a new MS tool, it never takes more than a year before they announce it's in maintenance mode and I am considered obsolete. (Good example of that, and of why it's not always as bad as it seems, is DirectShow. They say it's been replaced by WMF, but there are tons of things WMF still can't do, that DirectShow can, so it still exists and you still have to use it for a lot of things.)

Glad you're interested. I'll be looking forward to grappling with Visual Basic with your help.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you just want to change the appearance while (!) the button is pressed/clicked, I'd simply go for two DataTemplates, a setter for the default and a trigger for IsPressed:

<Button Width="24" Height="24">
 <Button.Resources>
  <DataTemplate x:Key="Unpressed">
    <Image Source="/Resources/Off.png"/>
  </DataTemplate>
  <DataTemplate x:Key="Pressed">
    <Image Source="/Resources/On.png"/>
  </DataTemplate>
 </Button.Resources>

 <Button.Style>
  <Style TargetType="{x:Type Button}">
    <Setter Property="ContentTemplate" Value="{StaticResource Unpressed}"/>
    <Style.Triggers>
     <Trigger Property="IsPressed" Value="True">
       <Setter Property="ContentTemplate" Value="{StaticResource Pressed}"/>
     </Trigger>
    </Style.Triggers>
  </Style>
 </Button.Style>
</Button>
 
Rancher
Posts: 515
11
Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know this is a verry old post but if you want to change your css when the mousebutton is pressed and change it back when released what's wrong with onMouseDown and onMouseUp?
 
Stevens Miller
Bartender
Posts: 1464
32
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Demesmaecker wrote:I know this is a verry old post but if you want to change your css when the mousebutton is pressed and change it back when released what's wrong with onMouseDown and onMouseUp?


Nothing, but this is WPF, not CSS. WPF's XAML can look a lot like CSS though.
 
Daniel Demesmaecker
Rancher
Posts: 515
11
Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stevens Miller wrote:
Nothing, but this is WPF, not CSS. WPF's XAML can look a lot like CSS though.



Lol sorry for the confussion, should have read the subjectline of this post a bit better
I never even heard before of WPF, but then I'm not to microsoft minded eather, it's microsoft's equivalent of swing or javaFx for java?
 
Daniel Demesmaecker
Rancher
Posts: 515
11
Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have no idea, so don't shoot me if my remark is everything but helpfull but there's something like MouseLeftButtonUp, could that be of use?
 
Stevens Miller
Bartender
Posts: 1464
32
C++ Java Netbeans IDE Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Demesmaecker wrote:I have no idea, so don't shoot me if my remark is everything but helpfull but there's something like MouseLeftButtonUp, could that be of use?


That's an event you can react to with code. But the XAML declaration defines characteristics that would apply to all instances of that class, without needing any code. That is (allegedlly) its great virtue: declarations are supposed to define "what" your application does, without having to be concerned with "how" it does it. That must have sounded appealing in an early white paper or something. In practice, it seems to mean there is no clear way to debug a XAML declaration. They don't "execute" in the sense that code executes. Yet, they define behavior. So figuring out where the behavior your want (or, when you are debugging, that you don't want) is defined can be quite a challenge.

JavaFX was supposed to follow the same declarative rubrick. I do not see that either JavaFX, nor WPF, have caught on all that much. CSS is everywhere, of course, but the Web is the Web, and an application is an application. Those are not yet the same thing.
 
Daniel Demesmaecker
Rancher
Posts: 515
11
Hibernate IntelliJ IDE Java MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for clearing that up for me...
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!