Disable focus on tabstop when TextBox is readonly - wpf

When a TextBox is in readonly and on tabbing i want to disable the focus border of the textbox, i wanted to do this in Style of textbox.Can any one help me to achieve this?
Updated the content:
Screenshot:

Place a condition like the below in your textbox style
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsReadOnly" Value="True"></Condition>
<Condition Property="IsFocused" Value="True"></Condition> </MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="BorderBrush" Value="{#7B2F81}"></Setter>
</MultiTrigger.Setters>

Try this:
<Window.Resources>
<Style x:Key="FocusVisualStyle" TargetType="{x:Type Control}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<Border SnapsToDevicePixels="True"
CornerRadius="0"
BorderThickness="2"
BorderBrush="#7B2F81" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Pink" />
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisualStyle}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBox Text="TestText"
IsReadOnly="True"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
If TextBox.IsReadOnly == True then set FocusVisualStyle in StyleTrigger. Visual behavior of Focus you can customize in FocusVisualStyle.

Related

How to set a border around listviewitem in WPF

My ListView should have following style:
no border around the whole ListView (achieved)
no highlighting when interacting with ListViewItem (achieved)
border around selected ListViewItem (missing)
My ListView:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- style selected item -->
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I tried this and this, both doesn't work for me. I guess my problem is the template but I have no idea how to put a border around the selected ListViewItem.
Update
Working solution:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Black"/>
<Setter TargetName="Border" Property="BorderThickness" Value="2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Maybe this works. Add a Border around ContentPresenter an use controlTemplate Triggers
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Red"/>
<Setter TargetName="Border" Property="BorderThickness" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

WPF Datagrid Selected Row Color and Centered Text

I have a simple DataGrid where I want to Style the selected row and center the text. I have tried the following and it does not work:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
Why will the above not work together? If I remove the trigger, it will center but the color I want will not be used.
Try add Grid to the ControlTemplate of DataGridCell style:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter Margin="2"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>

How do you change WPF DataGrid cell background while editing the cell?

The following is an example of how to set the background when the cell is selected, but when I actually click inside the cell to edit it the color changes. Is there a trigger property for when a cell is being edited? I'd like the background not to change.
<DataGrid Name="DG1" ItemsSource="{Binding}" SelectionUnit="Cell" >
<DataGrid.CellStyle>
<Style TargetType="DataGridCell" >
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="SeaGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</DataGrid>
Answering my own question, it looks like the Cell background color is based off of SystemColors.WindowBrushKey. Overriding that resource like such <SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="Red" /> did the trick.
`
You can add another trigger into your existing style for the IsEditing state. Then you can set the ControlTemplate for the DataGridCell inside of the trigger.
<Trigger Property="IsEditing" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Text, Mode=TwoWay, UpdateSourceTrigger=Default}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="0" BorderThickness="0" Background="SeaGreen"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
This works with DataGridTemplateColumn as well as other types like DataGridTextColumn, DataGridCheckboxColumn and etc.:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="CellBorder"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEditing" Value="True">
<Setter TargetName="CellBorder" Property="BorderBrush" Value="Green" />
<Setter TargetName="CellBorder" Property="Background" Value="yellow" />
<Setter TargetName="CellBorder" Property="BorderThickness" Value="1" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF buttons (image & label) shadowing

I want to create buttons which have a image and a text included and get a nice shadowing. Particularly, I want the image and label have a light grey shadowing, but when moving the mouse over the button I'd like a kind of blue shadowing. Moving away sets it back to light grey. I would need some help as I just can't figure out how to achive it (I'm new to WPF).
The Buttons looks like ...
<Button>
<Button.Content>
<StackPanel Orientation="Vertical">
<Image Source="Images/preferences-system.png" />
<Label HorizontalAlignment="Center">Settings</Label>
</StackPanel>
</Button.Content>
</Button>
The Canvas goes ...
<Canvas DockPanel.Dock="Left" Background="#FF349EBC">
<Canvas.Resources>
<DropShadowEffect x:Key="dropMouseOverShadow" Color="#FFD9EDF3" Opacity="80" Direction="270" />
<DropShadowEffect x:Key="dropLightShadow" Color="LightGrey" Opacity="10" Direction="270" BlurRadius="20" />
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" CornerRadius="2">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{StaticResource dropMouseOverShadow}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style TargetType="{x:Type Image}">
<Style.Setters>
<Setter Property="Effect" Value="{StaticResource dropLightShadow}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Label}">
<Style.Setters>
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontFamily" Value="Gill Sans MT" />
<Setter Property="Effect" Value="{StaticResource dropLightShadow}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</Canvas.Resources>
What I get is a light grey shadowing on image and labels on begin. Moving the mouse over the button the grey and light blue get mixed. When moving further on the image it gets the light blue only. The same goes for the label.
How can I achive switching the shadowning to light blue when I mouse over the button and not the image and label itself? Anyone an idea or an completly other approach?
Apply the LightGray Effect to the ContentPresenter. Then on the IsMouseOver Trigger, set the Effect property of the ContentPresenter to the blue Effect.
NOTE: Accomplish this by setting the x:Name attribute of the ContentPresenter, then accessing the ContentPresenter by name via the Setter using TargetName.
NOTE: Remove the various other Effect settings in the styles of the child elements. Applying the Effect to the ContentPresenter causes the child elements to inherit the Effect.
<Canvas DockPanel.Dock="Left" Background="#FF349EBC">
<Canvas.Resources>
<DropShadowEffect x:Key="dropMouseOverShadow" Color="#FFD9EDF3" Opacity="80" Direction="270" />
<DropShadowEffect x:Key="dropLightShadow" Color="LightGrey" Opacity="10" Direction="270" BlurRadius="20" />
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" CornerRadius="2">
<ContentPresenter x:Name="cp" Effect="{StaticResource dropLightShadow}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="cp" Property="Effect" Value="{StaticResource dropMouseOverShadow}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style TargetType="{x:Type Label}">
<Style.Setters>
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontFamily" Value="Gill Sans MT" />
</Style.Setters>
</Style>

Issues with ListBoxItem ControlTemplate design in WPF?

Here's my XAML:
<ListBox
Name="PlaylistListBox"
ScrollViewer.CanContentScroll="False"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Source={StaticResource ResourceKey=MyListBoxView}}"
ItemTemplateSelector="{Binding Source={StaticResource ResourceKey=MySelector}}"
MouseDoubleClick="PlaylistListBox_MouseDoubleClick" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border
Name="Border"
CornerRadius="4"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="Black" />
<!-- The following setter for opacity is giving me headaches -->
<Setter TargetName="Border" Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter
Event="Loaded"
Handler="PlaylistListBoxItem_Loaded" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Two issues:
Because of the Opacity setter, whole item is transparent by 50%. I want just the
border defined in the ListBoxItem ControlTemplate to be transparent and its content
to preserve full opacity.
How do I make a Setter/Trigger to make that same border red when the ListBox is not
in focus? It should be something like InFocus="False" and IsSelected="True".
Thanks for clarifying.
You should place another border underneath the content and make it half-transparent remaining the main content fully visible. You can accomplish this by using Grid and placing a "background" border in it first and then the content. This way you will set the opacity only on the background border, but not on the content;
You can use a MultiTrigger for that.
Here is the modified style that shows what I mean:
<ListBox
Name="PlaylistListBox"
ScrollViewer.CanContentScroll="False"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Source={StaticResource ResourceKey=MyListBoxView}}"
ItemTemplateSelector="{Binding Source={StaticResource ResourceKey=MySelector}}"
MouseDoubleClick="PlaylistListBox_MouseDoubleClick" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Border
Name="BackgroundBorder"
CornerRadius="4"
SnapsToDevicePixels="true">
</Border>
<Border Name="Border">
<ContentPresenter />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="BackgroundBorder" Property="Background" Value="Black" />
<!-- The following setter for opacity is giving me headaches -->
<Setter TargetName="BackgroundBorder" Property="Opacity" Value="0.5" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsFocused" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="BackgroundBorder" Property="Background" Value="Red" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter
Event="Loaded"
Handler="PlaylistListBoxItem_Loaded" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

Resources