Change Button Foreground in :pointerover and :pressed states - c#

In fluent theme i can't change button Foregrounds in this states. In Github i find this code:
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
...
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPointerOver}" />
</Style>
But my project can't build with Foreground on ContentPresenter#PART_ContentPresenter.

ContentPresenter does not have a Foreground property. If you target a TextBlock you could use attached property TextBlock.Foreground. If not, there are child and descendant selectors you may want to take look at.
Also the nested selector ^ does not seem to be documented (it's pretty new it seems), maybe it would be safer to just use name of the control (Button in your case) for now.

Related

Apply Style to every element of type X in UWP

I'm currently trying to find a way to style all controls in a UWP app with the same Style/type. To be specific I want to set OpticalMarginAlignment to TrimSideBearings for every - I mean every TextBlock.
I know I can create a Style in App.xaml without x:Key property like this:
<Style TargetType="TextBlock">
<Setter Property="OpticalMarginAlignment" Value="TrimSideBearings" />
</Style>
But this does not change the style of TextBlocks which are in a DataTemplate (which according to similar questions is by design). However I don't want to have to set a Style for each TextBlock used in a DataTemplate, so I thought about other solutions:
Create a StyledTextBlock element derived from TextBlock (not working cause TextBlock is sealed)
Create a StyledDataTemplate element derived from DataTemplate (not working cause I haven't found anything in DataTemplate I could hook into to load the Style and because there is no DataTemplate.Resources)
Create a StyledTextBlock element derived from UserControl with a TextBlock element inside
Number 3 is even working, though it would require me to create a DependencyProperty for every TextBlock.DependencyProperty I want to use to style the StyledTextBlock like this:
<StyledTextBlock Text="Example" FontSize="10" />
To keep code amount low I could create a TextStyle DependencyProperty in StyledTextBlock and set it like this, but I don't like this solution as well:
<StyledTextBlock Text="Example">
<StyledTextBlock.TextStyle>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10" />
</Style>
</StyledTextBlock.Style>
</StyledTextBlock>
Does anyone have another idea how to achieve this?

Change the control property globally in wpf

I have a back button which is copied almost to all the Controls in my application.
I have set the styles and properties of the button on each individual control (usercontrol)
Now I want to change the text property of the button of all the control (usercontrol).
I don't want to go and change the property of each control.
Please help me setting a global property which sets the property in one place.
Since the style is common to all pages. Create the style without a key/name, just the target type would do.
<Style TargetType="{x:Type Button}">
Then do either of the following -
Add it to the App.XAML for visibility throughout the app
Better approach would be to define a resource dictionary file and import it, wherever you need it.
<Style TargetType="{x:Type Button}">
<Setter Property="Text" Value="{Binding text}" />
<Setter Property="...." Value="{Binding ....}"/>
</Style>
Add this to App.xaml file as you want it to be global style for all your user controls.

Border thickness for Telerik's RadMaskedInputBaseStyle in Silverlight when content is invalid

How do I increase border thickness for RadMaskedInputBaseStyle (or RadMaskedDateTimeInput by Telerik) in Silverlight only WHEN it is red indicating that the input contains invalid entry.
My XAML looks like this
<Style TargetType="telerik:RadMaskedDateTimeInput">
<Setter Property="IsValidationHintVisible" Value="True" />
</Style>
In general, if a style isn't available as a property of the control, then you will find it buried somewhere in the control template (as Chris W alludes to in the comments).
To see the source for a proprietary control template like one of Telerik's, open up Expression Blend and click "Edit Template" on an instance of the control. If you do that for the RadMaskedDateTimeInput, you will notice the validation-related visual states making reference to an element named "ErrorElement". Scroll down, in the control template source, and you will see that is declared as follows:
<Telerik_Windows_Controls_Chromes:ValidationTooltip x:Name="ErrorElement" Opacity="0" TooltipPlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" telerik:StyleManager.Theme="{StaticResource Theme6}" TooltipContent="{TemplateBinding DisplayErrorMessage}" TooltipContentTemplate="{TemplateBinding ErrorMessageTemplate}" />
Ok, so it's another control called ValidationTooltip. This control does have a BorderThickness property exposed, so if you like, you should be able to simply set that property in a targeted global style. Something like this should go in your resource dictionary:
<Style xmlns:Telerik_Windows_Controls_Chromes="clr-namespace:Telerik.Windows.Controls.Chromes;assembly=Telerik.Windows.Controls"
TargetType="Telerik_Windows_Controls_Chromes:ValidationTooltip">
<Setter Property="BorderThickness" Value="2" />
</Style>

Alter a style from a parent

I have a custom class that is derived from userControl, it describes what features a "service window" should have. It should also describe how a instance of this "service window" should look.
I have a style called serviceStyle. now whenever i create a new instance of the service window, i have to manually set the style in the XAML of the instance, when possible i want to avoid having to do this by basically forcing the style to all childs of service window to serviceStyle. Then i want to be able to do a fade animation on a textBlock in serviceStyle. Now since this is the style of a child of the "Service window" it seems unreachable...
In the meantime i found a way to Set the Style as a default style for all the service windows, this can be done by adding this line in the constructor:
DefaultStyleKeyProperty.OverrideMetadata(typeof(NetcarityService), new FrameworkPropertyMetadata(typeof(NetcarityService)));
Now i need to be able to get from the source to the element textBlock in the xaml of the ServiceWindowStyle....
Thanks in advance.
You don't need to do that in order to make a default style, you just define your style without a key. For example, this style applies to all button in an app (if the style is defined in app.xaml)
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Margin" Value="6"></Setter>
<Setter Property="Padding" Value="6,3,6,3"></Setter>
</Style.Setters>
</Style>
With regards the children I would think you just need to write some code to detect when a child is added and set the default style for the child. I think you can just override OnVisualChildrenChanged.
PS. Setting DefaultStyleKeyProperty should be done in the static constructor

WPF Updating styles at runtime

I would like to update the default Window style dynamically at runtime so I can change the FontSize and FontFamily dynamically at runtime. I found that Styles in your resource dictionary are sealed at runtime and cannot be changed, so I used the following method of updating the style:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
</Style>
With the following code:
Style newStyle = (Make a copy of the old style but with the FontSize and FontFamily changed)
// Remove and re-add the style to the ResourceDictionary.
this.Resources.Remove(typeof(Window));
this.Resources.Add(typeof(Window), newStyle);
// The style does not update unless you set it on each window.
foreach (Window window in Application.Current.Windows)
{
window.Style = newStyle;
}
There are several problems with this approach and I have a few questions as to why things are the way they are.
Why are styles sealed at runtime and is there a way of making them unsealed?
When I re-add the new style, why is this not picked up by all of my windows? Why do I have to go and manually apply it to every window?
Is there a better way?
I would probably tackle this with a "settings service" which exposes properties for the various settings, and fires INPC as you would for normal binding. Next up I'd change that style to be something like:
<Style x:Key="MyWindowStyle">
<Setter Property="FontFamily" Value="{Binding Path=FontFamily, Source={StaticResource SettingsService}, FallbackValue=Arial}"/>
<Setter Property="FontSize" Value="{Binding Path=FontSize, Source={StaticResource SettingsService}, FallbackValue=12}"/>
</Style>
With your "settings service" defined as a static resource:
<services:SettingsService x:Key="SettingsService"/>
Then in each window make sure the style is set as a DynamicResource:
<Window Style="{DynamicResource MyWindowStyle}" .... >
There is often a lot of misunderstanding around the differences between Static and Dynamic resources, but the basic difference is Static is a "one time" setting whereas Dynamic will update the settings if the resource changes.
Now if you set those properties in your "settings service" they will fire INPC, which will update the Style, which the DynamicResource will pick up on and alter the Window properties accordingly.
Seems like a lot of work, but it gives you some nice flexibility, and all the "heavy lifting" is done purely using Bindings. We use a similar technique on a project I'm working on at the moment so when a user chooses a fill/stroke colour the various tools in the toolbar update to reflect the new values.

Categories