How to properly make a controltemplate for a slider in WPF? - c#

So I've been trying to override the default style for a slider, but I feel like the way I've been doing it is not correct. For one, I'd like to be able to highlight the track behind the thumb. How do I do this the correct way?
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type Slider}}"
TargetType="Slider"
x:Key="SliderTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Grid>
<Border VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Height="5"
Background="White"/>
<Track x:Name="PART_Track">
<Track.Thumb>
<Thumb x:Name="PART_Thumb">
<Thumb.Template>
<ControlTemplate>
<Border Height="20"
Width="20"
Background="#fff"
CornerRadius="15"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</ResourceDictionary>

You can change the track's color like this.
Get the default style by right-clicking the Slider and select Edit template then Edit a copy....
Change the color for <SolidColorBrush x:Key="SliderThumb.Track.Background" Color="HotPink"/>

Related

How to add a right margin to AvalonEdit number line?

I'm using AvalonEdit WPF control with a .Net Framework 4.8 project, using Visual Studio 2019 under Windows 10 64bit.
I need to add a right margin to the linenumbers. To understand what i need i attach a selfexplanatory image:
My actual xaml code is next:
<avalonEdit:TextEditor
Grid.Column="2" Grid.Row="2"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:editing="clr-namespace:ICSharpCode.AvalonEdit.Editing;assembly=ICSharpCode.AvalonEdit"
xmlns:rendering="clr-namespace:ICSharpCode.AvalonEdit.Rendering;assembly=ICSharpCode.AvalonEdit"
Name="TextEditor"
FontFamily="Consolas"
SyntaxHighlighting="C#"
ShowLineNumbers="True"
FontSize="10pt" Margin="0">
</avalonEdit:TextEditor>
Hope that someone can give me a hand on this, i spend two days trying to add this margin but couldn't achieve a proper solution. Thanks in advance.
While the approach in my comment will work, I thought of an even easier way. Just copy the style for TextArea from the source and modify it to include some margin on the right of the ItemsControl that contains all the editor's margins. The style is here:
https://github.com/icsharpcode/AvalonEdit/blob/395ef8166870e2c6e1f63a7d97ac22e5e646e790/ICSharpCode.AvalonEdit/TextEditor.xaml#L42
And here's a complete example:
<Window x:Class="WpfApp1_SO_AvalonEdit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:editing="clr-namespace:ICSharpCode.AvalonEdit.Editing;assembly=ICSharpCode.AvalonEdit"
Title="Main Window"
Width="800"
Height="450">
<Window.Resources>
<Style x:Shared="False" TargetType="{x:Type editing:TextArea}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SelectionBrush">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="#3399FF" />
</Setter.Value>
</Setter>
<Setter Property="SelectionBorder">
<Setter.Value>
<Pen>
<Pen.Brush>
<SolidColorBrush Color="#3399FF" />
</Pen.Brush>
</Pen>
</Setter.Value>
</Setter>
<Setter Property="SelectionForeground">
<Setter.Value>
<SolidColorBrush Color="White" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type editing:TextArea}">
<DockPanel Focusable="False">
<ItemsControl Margin="0,0,10,0" Focusable="False" ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LeftMargins}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<ContentPresenter Panel.ZIndex="-1" Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextView}" Focusable="False" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<avalonEdit:TextEditor Name="TextEditor" FontFamily="Consolas" FontSize="10pt" ShowLineNumbers="True" />
</Grid>

Styling ListViewItem in WPF [duplicate]

This is my XAML so far.
<ScrollViewer Grid.Column="1" Grid.RowSpan="2">
<ListBox Background="Black" ItemsSource="{Binding Path=ActiveLog}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Foreground="White">
<TextBlock >Date:</TextBlock>
<TextBlock Text="{Binding Path=LogDate}"/>
</TextBlock>
<TextBlock Grid.Column="1" Grid.Row="0" Foreground="White">
<TextBlock >Severity:</TextBlock>
<TextBlock Text="{Binding Path=Severity}"/>
</TextBlock>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Foreground="LightGray" Text="{Binding Path=Message}"></TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Template>
<ControlTemplate>
<StackPanel Background="Black" IsItemsHost="True" >
</StackPanel>
</ControlTemplate>
</ListBox.Template>
</ListBox>
</ScrollViewer>
The only problem is that the selected item has a blue box to the right. I assume there is a way to change the selection color, but I can't find it.
<UserControl.Resources>
<Style x:Key="myLBStyle" TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</Style.Resources>
</Style>
</UserControl.Resources>
and
<ListBox ItemsSource="{Binding Path=FirstNames}"
ItemContainerStyle="{StaticResource myLBStyle}">
You just override the style of the listboxitem (see the: TargetType is ListBoxItem)
Or you can apply HighlightBrushKey directly to the ListBox. Setter Property="Background" Value="Transparent" did NOT work. But I did have to set the Foreground to Black.
<ListBox ... >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
</Style.Resources>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
You need to use ListBox.ItemContainerStyle.
ListBox.ItemTemplate specifies how the content of an item should be displayed. But WPF still wraps each item in a ListBoxItem control, which by default gets its Background set to the system highlight colour if it is selected. You can't stop WPF creating the ListBoxItem controls, but you can style them -- in your case, to set the Background to always be Transparent or Black or whatever -- and to do so, you use ItemContainerStyle.
juFo's answer shows one possible implementation, by "hijacking" the system background brush resource within the context of the item style; another, perhaps more idiomatic technique is to use a Setter for the Background property.
I had to set both HighlightBrushKey and ControlBrushKey to get it to be correctly styled. Otherwise, whilst it has focus this will correctly use the transparent HighlightBrusKey. Bt, if the control loses focus (whilst it is still highlighted) then it uses the ControlBrushKey.
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</Style.Resources>
When Using .Net 4.5 and above, use InactiveSelectionHighlightBrushKey instead of ControlBrushKey:
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
</Style.Resources>
Hope this helps someone out.
I've tried various solutions and none worked for me, after some more research I've found a solution that worked for me here
https://gist.github.com/LGM-AdrianHum/c8cb125bc493c1ccac99b4098c7eeb60
<Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
<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="Yellow"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox ItemContainerStyle="{DynamicResource _ListBoxItemStyle}"
Width="200" Height="250"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBoxItem>Hello</ListBoxItem>
<ListBoxItem>Hi</ListBoxItem>
</ListBox>
I posted it here, as this is the first google result for this problem so some others may find it useful.
You have to create a new template for item selection like this.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ContentPresenter
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
If selection is not important, it is better to use an ItemsControl wrapped in a ScrollViewer. This combination is more light-weight than the Listbox (which actually is derived from ItemsControl already) and using it would eliminate the need to use a cheap hack to override behavior that is already absent from the ItemsControl.
In cases where the selection behavior IS actually important, then this obviously will not work. However, if you want to change the color of the Selected Item Background in such a way that it is not visible to the user, then that would only serve to confuse them. In cases where your intention is to change some other characteristic to indicate that the item is selected, then some of the other answers to this question may still be more relevant.
Here is a skeleton of how the markup should look:
<ScrollViewer>
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

WPF (Bug) FocusVisualStyle doesn't work for Window with Template

I have got the problem with FocusVisualStyle, I need to override TAB keyboard focus style, when i'm override Window.Template all controls styles FocusVisualStyle on the window stops working.
The problem XAML (Tab style doesn't work):
<Window
x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="450">
<Window.Style>
<Style TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
<Window.Resources>
<Style x:Key="ButtonTabFocused" TargetType="Control">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="-3" StrokeThickness="3" Stroke="Red" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Background="White">
<Button
Width="100"
Height="40"
Content="MyButton"
FocusVisualStyle="{StaticResource ButtonTabFocused}" />
</Grid>
</Window>
Without Window.Style FocusVisualStyle works well (Tab style works):
<Window
x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="450">
<Window.Resources>
<Style x:Key="ButtonTabFocused" TargetType="Control">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="-3" StrokeThickness="3" Stroke="Red" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Background="White">
<Button
Width="100"
Height="40"
Content="MyButton"
FocusVisualStyle="{StaticResource ButtonTabFocused}" />
</Grid>
</Window>
No msdn information founded. Could you please tell me any workarounds or am i missed something what's makes this behavior.
My environments:
.NET Framework 4.7.2 (same for older versions)
Windows 10 19042.685
Visual Studio 2019
Thanks.
UPDATE, working style below, thanks to arxont:
<Style TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<AdornerDecorator>
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You need to add AdornerDecorator. Change your window style:
<AdornerDecorator>
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</AdornerDecorator>

default textblock styling

I have the following checkbox
<CheckBox x:Name="checkBox" Content="CheckBox" Width="74"/>
and I have a button
<Button Name="TestButton" Content="Test" />
I want to set a "default" color for the textblock. I achieve that by having a resourcedictionary which has the following content:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White"/>
</Style>
The problem is, that the Button should still have a black Textblock foreground, but although in another sourcedictionary i have the following, it still changes to white:
<Style TargetType="Button">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="1,0,0,1" CornerRadius="5" Background="{TemplateBinding Background}">
<ContentPresenter
x:Name="ContentPresenter"
Margin="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextBlock.Foreground="Black"
Opacity="1.0"/>
</Border>
</ControlTemplate/>
<Setter.Value/>
</Setter>
</Style.Setters>
</Style
Edit:
The ResourceDictionaries are defined in Application.xaml like this:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TextBlock.xaml"/>
<ResourceDictionary Source="Buttons.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
You could try overriding the default TextBlock style locally for the ContentPresenter by defining another one in its Resources:
<ContentPresenter ... >
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
But a better way to set a default control text color is like this in App.Resources. TextElement.Foreground will override this on any given individual element.
<SolidColorBrush
x:Key="{x:Static SystemColors.ControlTextBrushKey}"
Color="White"
/>
If you use that and discard your default TextBlock style, your original ContentPresenter should work as you had it.

ThemeResources not resolved in Windows Phone XAML

Here is my problem:
In my application for WP 8.1, I have to make a button with an image, and this image have to change according to the theme used in the device,otherway it will be hidden by the background.
So I've tryed using ThemeResource. But it can't be resolved.
Here is the code:
MainPage.xaml
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonImage.xaml"/>
</ResourceDictionary.MergedDictionaries>
....
<Button HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="40" Height="40"
MinWidth="0" MinHeight="0"
Padding="0"
BorderThickness="1.5"
Grid.Column="2"
Style="{ThemeResource Button123}"/>
ButtonImage.xaml
<Style x:Key="ButtonImage" TargetType="Button">
...
</Style>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Black" x:Key="Black">
<Style x:Key="ButtonAZ" BasedOn="{StaticResource ButtonImage}" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Image Source="Assets/AtoZWhite.png"></Image>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Button123" BasedOn="{StaticResource ButtonImage}" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Image Source="Assets/123White.png"></Image>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary x:Name="White" x:Key="White">
<Style x:Key="ButtonAZ" BasedOn="{StaticResource ButtonImage}" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Image Source="Assets/AtoZBlack.png"></Image>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Button123" BasedOn="{StaticResource ButtonImage}" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Image Source="Assets/123Black.png"></Image>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
Can some one tell me why is impossibile to use the themeResources??
What kind of image is it? Is it just a black & white icon in Windows Phone Modern style? If so, you can use it in BitmapIcon and Windows Phone will color it for you. Here's my example with 64x64 image.
<Button>
<BitmapIcon UriSource="Assets/Smile.png"
Width="64"
Height="64"/>
</Button>
This is the image:
But in the app it will look like this:
or this
...depending on your phone settings.
According to MSDN, the appropriate keys to use for you dictionaries are Light and Dark, not Black and White. See the documentation.

Categories

Resources