Styling ComboBox when DropDown opens and closes in WPF - wpf

i am wondering if it's possible to create styles in XAML to the events of a Control. To properties i know that is possible, but and to the Events?
What i need is to apply some styles to a ComboBox when the DropDown opens, and then apply other style after DropDown closes. Is possible to create a style in XAML to this event or any other one?
This is easy to do when he create the event in the code behind and it will do whatever we want, but i am wondering if it's possible to prevent that and simply create a Style.
And anyway it's a Style that i will apply in more than one ComboBox, and so it's why i don't want to create one event per ComboBox.

Do you really need the events? How about this:
<Style TargetType="{x:Type ComboBox}">
<!-- Default style setters here -->
<Style.Triggers>
<Trigger Property="IsDropDownOpen" Value="True">
<!-- Opened style setters here -->
</Trigger>
</Style.Triggers>
</Style>

Related

WPF styling deep nested elements

I can't override a default style attribute of a third-party component that I use in a clean way. The visual tree looks something like this:
A
--B
...
------------Z
--------------TextBlock
I try to override the style of TextBlock like this:
<Style
TargetType="A">
<Style.Resources>
<Style
TargetType="TextBlock">
<Setter
Property="TextWrapping"
Value="Wrap" />
</Style>
</Style.Resources>
</Style>
But this doesn't work. In live visual tree, I confirm that component A sees my custom style but TextBlock doesn't see it. However, when I try:
<Style
TargetType="Z">
<Style.Resources>
<Style
TargetType="TextBlock">
<Setter
Property="TextWrapping"
Value="Wrap" />
</Style>
</Style.Resources>
</Style>
It works though. Therefore, it seems to me that WPF forces me to add all of the child components one by one as Style.Resources to be able to edit the innermost child. But I don't want to define all of the resources between component A to Z just to add one simple style. What are my options?
I'm not sure if I fully understand your question, as you've provided a working answer, and I can't see why would WPF force you to 'define all of the resources between component A to Z'.
However, here is a tip:
You can create a custom control that inherits Z and overrides OnApplyTemplate(). When OnApplyTemplate() is called you're guaranteed that the template was applied, so you can find any child control (your textbox) you want. (Just google for e.g 'wpf find child control by name' if you don't know how.) Once you have your textbox, you can change its' wrapping from code.
I had to customize a Ribbon control once, and that approach greatly simplified the task.

WPF: Why are nested styles not always working?

I'm trying to apply a nested WPF style to a Toolbar. I'd like to have all children of the Toolbar (MenuItems, Buttons, ToggleButtons etc.) to have the specified style.
The problem is, that the nested style definition is applied correctly to some controls like MenuItems, but not to Buttons.
What am I doing wrong?
The MenuItem is correctly placed at the bottom of the Toolbar, but the ToggleButton is in the middle:
<Window.Resources>
<Style x:Key="MyToolbarStyle" TargetType="ToolBar">
<!-- Setters for Toolbar properties -->
<Setter Property="Height" Value="80" />
<!-- Nested setters for children of the Toolbar -->
<Style.Resources>
<Style TargetType="MenuItem">
<Setter Property="VerticalAlignment" Value="Bottom" />
</Style>
<Style TargetType="ToggleButton">
<Setter Property="VerticalAlignment" Value="Bottom" />
</Style>
</Style.Resources>
</Style>
</Window.Resources>
<Grid >
<ToolBar VerticalAlignment="Top" Style="{StaticResource MyToolbarStyle}">
<MenuItem Header="MyMenuItem" /> <!-- Appears on the bottom like defined in the style-->
<ToggleButton Content="MyToggleButton" /> <!-- Nested style does not seem to be applied-->
</ToolBar>
</Grid>
The WPF ToolBar is a special type of control that defines some custom styles for some WPF controls like Button, ToggleButton... full list here, you can identify them by ElementName + StyleKey property name. If you'd like to change a default style for a specific control you will have to modify one of these styles.
Try replacing your style for the ToggleButton with the following:
<Style x:Key="{x:Static ToolBar.ToggleButtonStyleKey}" TargetType="ToggleButton">
<Setter Property="VerticalAlignment" Value="Bottom" />
</Style>
What you are doing wrong is thinking that WPF Styles are like CSS styles. In WPF, Styles are just not used that way. Sure, if we could, we'd probably save a few lines of XAML, but we can't. The best that we can do is what you have done... I'm assuming that you've created a Style for a top level element like Control. As you have seen, not all controls will extend the Control class, so the Style won't be applied to all of them.
Instead, Styles in WPF are more like the .class styles in CSS... one Style per type and then we can apply a further Style per UI element. There are lots of situations like this in WPF where we wish we could write less code, but it is how it is and the sooner that everybody realises it, the better.
UPDATE >>>
In response to your first comment, you seem to be mistaken. Just to clarify, if what you are calling nested Styles are the Styles that you defined in the outer Style.Resources section, then there is nothing wrong with that... no problem what-so-ever. Just take those inner Styles out of the Resources section and you will see the same UI.
Now you're probably thinking of changing your question title to something like 'Why isn't my default ToggleButton Style being applied inside a ToolBar control?'. While I can't say for sure, I can only assume that this behaviour is caused by a Style that has been defined within the ToolBar ControlTemplate.
I'm thinking that because of the following points:
A custom implicit Style (no x:Key) will not work inside the ToolBar control.
A custom explicit Style (named) will work as expected inside the ToolBar control.
A Style property set on the element will work as expected inside the ToolBar control.

Xaml Grid Styling

New to WPF, I'm having some trouble creating a styles in my code, I was able to make some buttons styles by drawing rectangles and making them into buttons, this opened a template editor so I was able to do it.
Now I'm wanting to create a template for a repeating stackpanel/grid layout, and I wrote it by hand this time, but I am getting an error that says the "template is not a valid member"
This is the kind of thing I was trying to create, but the Property="Template" bit is underlined in red. Can somebody explain to me the reason behind this? How do I create or initialize the template?
<Style x:Key="LaneStyle" TargetType="{x:Type Grid}">
<Setter Property="Width" Value="760"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Grid}">
<!-- Things here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If someone could direct me to a tutorial on styles/templates that would be nice as well, haven't been able to find one that explained it in more detail.
Grid is not a control, therefore you cannot apply a ControlTemplate to it. If you're looking for a "repeater" kind of thing, you should be using an ItemsControl.
The best way to create templates/styles is by using Microsoft Blend 3.0/4.0
Over there one can easily find out what's the progress after doing each change.
In your case, a grid cannot be styled as it is a container not a control. If you wish to customize some control need to modify the control template of the control.

What is the most economical way to implement your own window border and title bar?

I am pretty new to WPF and am sitting here with my book trying to figure out the best approach to this application.
The title bar is not part of the client area so I am making my own title bar.
Which way would it be easiest to make this into some sort of resource to apply to all new windows I create?
<Application.Resources>
<Style x:Key="WindowTheme">
<Setter Property="Window.WindowStyle" Value="None"/>
</Style>
<!--Would I create a user control here for the title bar/border and title bar buttons? Or would it be a style?-->
</Application.Resources>
In WPF, there are two ways to use styles: Named styles and typed styles. A named style has an x:Key="..." attribute. A typed style doesn't have a name, but a TargetType="..." attribute (Rem: Named styles can and very often do have a TargetType as well, so named styles and unnamed styles would be more precise). Typed styles automatically get applied to all controls in the scope, which are of type TargetType (not a derived type).
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="Blue" />
</Style>
To create your own window, you can set it's template property to a UserControl in the style:
<Style TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The professional way to implement the control template is to implement it 'from scratch', this means not using a UserControl which derives from Window. To do this, you define the visual tree of the Window, and use the WPF feature TemplateParts to define what part of your control template is responsible for what functionality of the window.
Here is a tutorial which describes pretty exactly what you want to do:
CodeProject tutorial

WP7 Disabled Button Style

I am trying to do change the color of a disabled button's border/text.
Code:
<Style x:Key="TopTabChooserButtonDisabled" TargetType="Button">
<Setter Property="Foreground" Value="Orange" />
</Style>
But it doesn't affect the button at all in Silverlight. Does anybody know what will make it change? THanks.
You can do this fairly easily by retemplating the control in blend.
Rclick the control, edit template, edit a copy. You then have access to all the states and constituent objects that make up the control in each of those states to change properties of each as needed.

Resources