WPF Change focused TextBox background color - c#

Note: I'm using MahApps.Metro.
So what I wanted is to create a global style which affects all TextBoxes in the application. Style should on Focus (whether it's a mouse, keyboard, whatever) change the background of the focused TextBox.
My problem is similar to
Change the focused border color of a Wpf textbox when it GotFocus()
I still suck with styles and templates. This is the code they used.
<Style
BasedOn="{StaticResource {x:Type TextBox}}"
TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border
x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<ScrollViewer
x:Name="PART_ContentHost"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="border" Property="Opacity" Value="0.56" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="#FF7EB4EA" />
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How do I write a control template similar to this one that changes the Background, instead of Border?
Since I'm using Metro, I have to extend base TextBox- otherwise I lose everything pre-configured.
I also noticed that using the template above moved my pointer a bit up and also it shortened its height. It's probably overriding the pointer settings too?

Actually, if you only need to change the background, then you don't need to create a template. You can achieve the same result with a simple style.
Here is the markup:
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MetroTextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
BasedOn="{StaticResource MetroTextBox}" this part indicates that we are extending the TextBox style from Mahapps (you can find the resource name of the control to extend by just looking in the code, for example here is their TextBox style - https://github.com/MahApps/MahApps.Metro/blob/c26b33d114aec64d98afd4f729b28838583d8ed9/src/MahApps.Metro/MahApps.Metro/Styles/Controls.TextBox.xaml#L12).
Hope this will help.

Related

Setting BorderBrush of Button with a custom template and triggers

I'm trying to change the borderbrush property of a button in a custom template. Changing the background on mouseover using this method works just fine, but the BorderBrush? Nada.
Here's my code:
<Style x:Key="ImageButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Margin="1,0,0,-9">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,1,0" Height="94" Width="101"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit: Actually not even the blue borderbrush set at the beggining shows up so that may be of relevance.
Here's where the style is used if of any importance.
<Button Margin="191,10,138,109" Style="{StaticResource ImageButtonStyle}">
<Image/>
</Button>
You create style setting BorderThickness to 3 but then override default visual tree so this thicknes is not taken into acount. Add this
BorderThickness="{TemplateBinding BorderThickness}"
in order to see it.

How do I apply the textbox SelectionBrush property to a listbox item?

As opposed to using the default highlight brush, I want the color of a selected list box item to be the same as the color of selected text in a text box. I'm thinking it would be a x:Reference, but what if I need to do this at the control template triggers level inside a style element?
<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The setter value for the is selected trigger is what I want to make equal to the text selection brush.
As I see it, you`re almost there. Judging by TextBoxBase.SelectionOpacity property, default Opacity for selection brush is 0.4 so we have to emulate that:
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}"
Opacity="0.4" />
</Setter.Value>
</Setter>
</Trigger>
I tested it and it looks exactly like selected text background in TextBox.

Rounded Corner TextBox in WPF

i search the web for TextBox with rounded corners and find a xaml code like below:
<Style TargetType="{x:Type my1:CustomTextBox}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate >
<Border Background="{TemplateBinding Background}" x:Name="Bd"
BorderThickness="2" CornerRadius="5" BorderBrush="#FFF9EAB6">
***<ScrollViewer x:Name="PART_ContentHost" />***
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="BorderBrush" Value="#FFC7B0B0"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="Bd" Property="BorderBrush" Value="#FFC7B0B0"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="False">
<Setter Property="Foreground" Value="#FFC7B0B0"/>
</Trigger>
<Trigger Property="Width" Value="Auto">
<Setter Property="MinWidth" Value="120"/>
</Trigger>
<Trigger Property="Height" Value="Auto">
<Setter Property="MinHeight" Value="27"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
i want to find out what is
<ScrollViewer x:Name="PART_ContentHost" />
in detail and why not properly work my template if delete this line from it,
please tell me completely in detail.
thanks alot.
The part named "PART_ContentHost" contains the control core, this is the textbox itself, besides the adornments. The textbox's code behind will look for it, so if you rename of delete, the control wont work.
In this case, the content is scrollable (as a textbox can scroll text horizontally and vertically).
use this part of xaml deign :
<TextBox x:Name="usernameText" Height="30" Width="300" TextWrapping="Wrap" Text="" FontSize="20" HorizontalContentAlignment="Center" LostFocus="usernameText_LostFocus">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="10"/>
</Style>
</TextBox.Resources>
</TextBox>
If you need a simple textbox with rounded corners, you can do it like that:
<Border Padding="5" CornerRadius="5" BorderThickness="1" BorderBrush="LightGray" SnapsToDevicePixels="True" Background="White">
<TextBox Background="Transparent" BorderThickness="0">This is beautifull ;)</TextBox>
</Border>
The ScrollViewer contains the actual content of the control. Your control isn't a real textbox, but actually a border (with rounded corners) surrounding a ScrollViewer, into which you would then need to place your text. If you don't need scrolling, you can replace the ScrollViewer with a text box, i.e.:
change
<ScrollViewer x:Name="PART_ContentHost" />
to
<TextBox x:Name="PART_ContentHost" />

Turn off ListView border mouseover animations

ListView's default style animates the border colour to light blue when you mouse over the control. Is there any way of turning this off without replacing the entire control template?
I've tried
<ListView>
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="BorderBrush" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
</ListView>
This results in a green border, which turns briefly red when you mouse over before fading to light blue. The default animations take precedence.
Am I missing something simple, or is it time for a template override?
You would have to override the ControlTemplate, as the default one uses a ListBoxChrome element which creates the effect you see. ListBoxChrome ignores the BorderBrush property when the mouse is over, as determined by it's RenderMouseOver property.
You can still use ListBoxChrome if you want, you would just have to remove the RenderMouseOver property. Assuming you are using a GridView you'd use:
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
...
<Style x:Key="{x:Static GridView.GridViewStyleKey}"
TargetType="{x:Type ListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<theme:ListBoxChrome Name="Bd"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"
SnapsToDevicePixels="true">
<ScrollViewer Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}"
Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</theme:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you want to remove the focused look, then it probably better to just replace the ListBoxChrome with a Border element.

Remove list box item dotted border

I have a custom styled ListBoxItem with a Border surrounding a ContentPresenter. (Code found below). My border acts as my selection indicator and turns grey when you select it. All is fine when I use the mouse, but the moment I use my keyboard, an ugly dotted grey border comes out. How do I remove it?
Pics:
You can see that when I mouse over/click on the ListBoxItem, a border with included background surrounds the item. But an ugly dotted border pops out when I use the keyboard.
Code:
<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<StackPanel>
<Border Name="HighlightBorder"
Padding="30"
BorderBrush="Transparent"
BorderThickness="1"
CornerRadius="5"
>
<ContentPresenter/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HighlightBorder" Property="Background" Value="#F3F3F3"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="HighlightBorder" Property="Background" Value="#DFDFDF"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="HighlightBorder" Property="Background" Value="#DFDFDF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
From this answer by jobi-joy
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> ....

Categories

Resources