Volume Slider CustomControl - wpf

I searched the last hours for a custom control that looks like this:
Triangular volume control
It's like a simple slider, but this growing size to the right side is my problem.
I don't know how to do this.
Have anyone an idea?

You can define a geometry that has the shape of a triangle and use that as a OpacityMask of the Track. The Track has a repeat button on the left to decrease the value and on the right to increase it. You just need to bind the background of the left button to the background of your slider along with the background of the thumb. You also should make the templates of both the thumb and the repeaters very simple to only show the background color.
Here is an example style:
<Style TargetType="{x:Type Slider}">
<Setter Property="Background" Value="Gray"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Slider}">
<ControlTemplate.Resources>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<PathGeometry x:Key="Triangle">
<PathFigure StartPoint="0,1">
<LineSegment Point="1,1"/>
<LineSegment Point="1,0"/>
<LineSegment Point="0,1"/>
</PathFigure>
</PathGeometry>
</ControlTemplate.Resources>
<Grid>
<Grid>
<Grid.OpacityMask>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black" Geometry="{StaticResource Triangle}"/>
</DrawingBrush.Drawing>
</DrawingBrush>
</Grid.OpacityMask>
<Track Name="PART_Track" Value="{TemplateBinding Value}">
<Track.Thumb>
<Thumb Width="10" Background="{TemplateBinding Background}">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
<Track.DecreaseRepeatButton>
<RepeatButton Background="{TemplateBinding Background}" Command="Slider.DecreaseLarge"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Background="Transparent" Command="Slider.IncreaseLarge"/>
</Track.IncreaseRepeatButton>
</Track>
</Grid>
<Path
Data="{StaticResource Triangle}"
Stretch="Fill"
Stroke="Black"
StrokeThickness="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(This is just an example which disregards a lot of things like e.g. the Orientation)

Related

WPF styling tab items as arrow-like

I want to style my TabControl to have items similar to this:
I tried to the combination of Border (with right thickness of 0) and triangle shaped polygon with pushing the polygon out of bound a bit to overlap, but its not really working as the out of bounds part of polygon gets hidden. Here is my attempt and now I am stuck and don't really know what else to try:
<!-- Styles -->
<Style TargetType="{x:Type TabItem}">
<Setter Property="Padding" Value="15 0 15 0" />
<Setter Property="Background" Value="#f5f5f5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid ClipToBounds="False">
<Border x:Name="PART_Border"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderThickness="1 1 0 1"
BorderBrush="LightGray">
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" />
</Border>
<Polygon Points="0,0 20,25, 0,50"
Stroke="#e8e8e8"
Fill="#ffffff"
HorizontalAlignment="Right"
Margin="0 0 -10 0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="PART_Border" Property="Background" Value="#ffffff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Content -->
<TabControl>
<TabItem Header="First" />
<TabItem Header="Second" />
<TabItem Header="Third" />
</TabControl>
This will do the job for you:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="#f5f5f5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Path x:Name="Back" Data="M0,0 L 80,0 L100,20 L80,40 L0,40 L 20,20 " Stretch="None" VerticalAlignment="Stretch"
Stroke="#e8e8e8" StrokeThickness="2"
Fill="{TemplateBinding Background}"
HorizontalAlignment="Stretch" Margin="-30,0,0,0"/>
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Back" Property="Fill" Value="#ffffff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Instead of the border and polygon I used a Path to draw the shape for you.
You can use - (minus) values in margins to overlap items.
Result:

Need help overriding a WPF button style background color.

I have the below code set for a custom button. But I want to change the background for a single button.
<Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="rectangle" Fill="#FF2F2FEA" Stroke="Black">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="3"/>
</Rectangle.Effect>
</Rectangle>
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Bottom" Margin="2.833,0,2.5,1.162" RenderTransformOrigin="0.5,0.5" Width="69.667"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
The code below is meant to override the background color but doesn't. What am I missing? Thanks
<Style x:Key="SpecialButton" TargetType="Button" BasedOn="{StaticResource myButtonStyle}">
<Setter Property="Background" Value="PaleGreen" />
<Setter Property="Height" Value="19.96" />
</Style>
Add <Setter Property="Background" Value="#FF2F2FEA" /> to the myButtonStyle. And change the Fill on the Rectangle to Fill="{TemplateBinding Background}"
<Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FF2F2FEA" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="rectangle" Fill="{TemplateBinding Background}" Stroke="Black">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="3"/>
</Rectangle.Effect>
</Rectangle>
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Bottom"
Margin="2.833,0,2.5,1.162"
RenderTransformOrigin="0.5,0.5" Width="69.667"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
After this, the two Buttons should show up properly.
<StackPanel>
<Button Content="BASE" Style="{StaticResource myButtonStyle}"></Button>
<Button Content="DERIVED" Style="{StaticResource SpecialButton}"></Button>
</StackPanel>
Result:
Explanation: if you change the Template of a Control you have to "wire-up" its properties (like Background, Foreground, HorizontalContentAlignment etc) to properties of elements in the ControlTemplate. After all you want to give the ability to end users of the control to modify the color, alignment etc, and not just have a Control with a static visual tree.

Wpf vertical progress bar styling

could you please help with styling vertical progress bar with solid color?
I've been able to create this style
<Style TargetType="{x:Type ProgressBar}" x:Key="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid>
<Rectangle Name="PART_Track" StrokeThickness="1" >
<Rectangle.Fill>
<SolidColorBrush Color="#FF00FF00"></SolidColorBrush>
</Rectangle.Fill>
</Rectangle>
<DockPanel Margin="1">
<Rectangle Name="PART_Indicator">
</Rectangle>
<Rectangle Name="Mask" MinWidth="{TemplateBinding Width}" Fill="#C0C0C0"/>
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But it still is oriented horizontally and I don't know how to change it.
There is a ControlTemplate.Triggers in the default Template. This trigger rotates the angle by -90°.
If you add
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="LayoutTransform" TargetName="TemplateRoot">
<Setter.Value>
<RotateTransform Angle="-90"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
to your control and name the parenting grid "TemplateRoot" you can set the orientation.
Here's your template
<Style TargetType="{x:Type ProgressBar}" x:Key="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot">
<Rectangle Name="PART_Track" StrokeThickness="1" >
<Rectangle.Fill>
<SolidColorBrush Color="#FF00FF00"></SolidColorBrush>
</Rectangle.Fill>
</Rectangle>
<DockPanel Margin="1">
<Rectangle Name="PART_Indicator">
</Rectangle>
<Rectangle Name="Mask" MinWidth="{TemplateBinding Width}" Fill="#C0C0C0"/>
</DockPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="LayoutTransform" TargetName="TemplateRoot">
<Setter.Value>
<RotateTransform Angle="-90"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Change property of "super/base" style wpf

I am creating a base style. I am using inheritance to implement my base style. I know how to add properties on my derived class but I don't know how to just change a property. Let me give you an example:
let say I have this base style:
<!-- SrollViewer ScrollBar Repeat Buttons (at each end) -->
<Style x:Key="ScrollBarLineButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border
Name="Border"
Margin="1"
CornerRadius="2"
Background="WhiteSmoke"
BorderThickness="1">
<Image Stretch="Uniform" Source="/FilesPro;component/Images/scrollArrow.png" Height="40" VerticalAlignment="Center" HorizontalAlignment="Center" Width="52" >
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" />
<TranslateTransform Y="40"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<!--
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{StaticResource GlyphBrush}"
Data="{Binding Path=Content,
RelativeSource={RelativeSource TemplatedParent}}" >
</Path>
-->
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I would like to create a new style that has the same properties as ScrollBarLineButton but with the image transfrom scaleY=1 instead of -1.
when I do:
<Style x:Key="ScrollBarLineButtonVerticalUp" BasedOn="{StaticResource ScrollBarLineButton}" TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border>
<Image Stretch="Uniform" Source="/FilesPro;component/Images/scrollArrow.png" Height="40" VerticalAlignment="Center" HorizontalAlignment="Center" Width="52" >
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="1" />
....
...
border no longer has its base style margin, Background color etc.. How could I inherit from the style and just change one property. I know I can copy paste but I will change this a lot and it is convenient that if I change it in one place it changes in all the other places.
You can create a DynamicResource reference to do something like this, here's an example:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="ButtonStyleA" TargetType="{x:Type Button}">
<Style.Resources>
<SolidColorBrush x:Key="TextBrush" Color="Yellow" />
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="10" BorderThickness="1" BorderBrush="Red">
<ContentPresenter TextElement.Foreground="{DynamicResource TextBrush}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonStyleB" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyleA}">
<Style.Resources>
<SolidColorBrush x:Key="TextBrush" Color="Blue" />
</Style.Resources>
</Style>
</StackPanel.Resources>
<Button Style="{StaticResource ButtonStyleA}" Content="Lorem Ipsum" />
<Button Style="{StaticResource ButtonStyleB}" Content="Lorem Ipsum" />
</StackPanel>
In StyleB the TextBrush is overridden which causes the template to change as well since it references this resource.

How do I set the height of a wpf slider control's thumb

I want to put a slider in a datagrid cell and the row has a height of 20, so i'd like to make the height of the thumb of the slider smaller than that. I set the height of the slider itself, but the thumb appears to be cut off (i.e. it doesn't scale down to the height that I specify in the slider.height property). I don't want to have to override the entire control template of the slider control to do this. There's got to be some way of setting a property or something like that.
Edit: Even when I create a custom slider style which includes the custom thumb style with the sizes I want, it still doesn't size right.
Any ideas?
<Slider.LayoutTransform>
<ScaleTransform ScaleY="0.9" CenterX="15" CenterY="15"/>
</Slider.LayoutTransform>
Not very sexy, but it works like a charm when combined whith the Slider.Height/Slider.Width properties !
Set thumb style:
<Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<!--<Ellipse
Name="Ellipse"
Fill="Yellow"
Stroke="Yellow"
Height="10"
Width="{Binding Path=ThumbWidth, RelativeSource={RelativeSource TemplatedParent}}"
StrokeThickness="1" />-->
<Rectangle
Fill="Azure"
Stroke="Azure"
Height="7"
Width="{Binding Path=ThumbWidth, RelativeSource={RelativeSource TemplatedParent}}"
StrokeThickness="1"
Margin="0.1,.1,.1,.1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then use this style slider custom control
<Style TargetType="{x:Type local:NvSliderControl}">
<Setter Property="Orientation" Value="Vertical" />
<Setter Property="Height" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NvSliderControl}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Track x:Name="PART_Track" >
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumbStyle}">
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources