Vertical slider with ticker captions
I am currently trying to get a custom vertical ticker slider as well as the labels in those tickers with the corresponding values. I have already found some interesting code for the horizontal slider on the internet that I am currently using in my solution and looks like this:
XAML:
<ControlTemplate x:Key="HorizontalSlider" TargetType="{x:Type Slider}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="{TemplateBinding Slider.MinHeight}"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:MyTickBar Margin="5,0,10,0" x:Name="TopTick" SnapsToDevicePixels="True" Placement="Top" Fill="{StaticResource GlyphDarkBrush}" Height="5" />
<Border Name="TrackBackground" Margin="0" CornerRadius="2" Height="4" Grid.Row="1" Background="{StaticResource GlyphLightBrush}" BorderBrush="{StaticResource ButtonNormal}" BorderThickness="1" />
<Track Grid.Row="1" Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.DecreaseLarge" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumbStyle}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderButtonStyle}" Command="Slider.IncreaseLarge" />
</Track.IncreaseRepeatButton>
</Track>
<TickBar Name="BottomTick" SnapsToDevicePixels="True" Grid.Row="2" Fill="Black" Placement="Bottom" Height="10" Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TickPlacement" Value="TopLeft">
<Setter TargetName="TopTick" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="TickPlacement" Value="BottomRight">
<Setter TargetName="BottomTick" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="TickPlacement" Value="Both">
<Setter TargetName="TopTick" Property="Visibility" Value="Visible"/>
<Setter TargetName="BottomTick" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Since MyTickBar is a class, defined as:
public class MyTickBar : TickBar
{
protected override void OnRender(DrawingContext dc)
{
Size size = new Size(base.ActualWidth, base.ActualHeight);
int tickCount = (int)((this.Maximum - this.Minimum) / this.TickFrequency) + 1;
if ((this.Maximum - this.Minimum) % this.TickFrequency == 0)
tickCount -= 1;
Double tickFrequencySize;
// Calculate tick setting
tickFrequencySize = (size.Width * this.TickFrequency / (this.Maximum - this.Minimum));
string text = "";
FormattedText formattedText = null;
double num = this.Maximum - this.Minimum;
int i = 0;
// Draw each tick text
for (i = 0; i <= tickCount; i++)
{
text = Convert.ToString(Convert.ToInt32(this.Minimum + this.TickFrequency * i), 10);
formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 16, Brushes.Black);
dc.DrawText(formattedText, new Point((tickFrequencySize * i), 30));
}
}
}
This works great with a horizontal slider, but when I pretend to be vertical I tried two different solutions with no success. Firstly, there was a need to create a similar XAML for the vertical slider, but since I am fairly new to WPF, I was unable to reach the intended solution (I basically changed the row and height properties to column and from, but probably a little more complicated than that ). And my second attempt was to use
<Slider.LayoutTransform>
<RotateTransform Angle="270"/>
</Slider.LayoutTransform>
on a fake slider, getting the slider with labels in the wrong position, as shown in the following image: http://s22.postimage.org/sophl10wh/Incorrect.jpg
I tried to apply rotation to the DrawingContext MyTicker, but it rotates the whole ticker, not the value labels. So my question is, how can I get a fake solution? Either by making the necessary changes to the new XAML for the custom vertical slider, or by rotating the labels in the second solution.
source to share
So now I can answer my own question and maybe help someone in the future who will try to do this. As I said in a comment to my own question, it was only later that I realized that I could go to msdn and get the correct vertical slider template instead of trying to adapt the horizontal one.
Now my current XAML:
<ControlTemplate x:Key="VerticalSlider" TargetType="{x:Type Slider}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" MinWidth="{TemplateBinding Slider.MinWidth}"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<local:MyTickBarVertical Margin="0,0,0,10" x:Name="TopTick" SnapsToDevicePixels="True" Placement="Left" Fill="{StaticResource GlyphDarkBrush}" Width="4" />
<Track Grid.Column="1" Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton
Style="{StaticResource SliderButtonStyle}"
Command="Slider.DecreaseLarge" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumbStyle}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton
Style="{StaticResource SliderButtonStyle}"
Command="Slider.IncreaseLarge" />
</Track.IncreaseRepeatButton>
</Track>
<TickBar
Name="BottomTick"
SnapsToDevicePixels="True"
Grid.Column="2"
Fill="Black"
Placement="Right"
Width="4"
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TickPlacement" Value="TopLeft">
<Setter TargetName="TopTick" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="TickPlacement" Value="BottomRight">
<Setter TargetName="BottomTick" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="TickPlacement" Value="Both">
<Setter TargetName="TopTick" Property="Visibility" Value="Visible"/>
<Setter TargetName="BottomTick" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
and I had some small changes in my class since I am now using the correct vertical slider:
public class MyTickBarVertical : TickBar
{
protected override void OnRender(DrawingContext dc)
{
Size size = new Size(base.ActualWidth, base.ActualHeight);
int tickCount = (int)((this.Maximum - this.Minimum) / this.TickFrequency) + 1;
if ((this.Maximum - this.Minimum) % this.TickFrequency == 0)
tickCount -= 1;
Double tickFrequencySize;
// Calculate tick setting
//width to height
tickFrequencySize = (size.Height * this.TickFrequency / (this.Maximum - this.Minimum));
string text = "";
FormattedText formattedText = null;
double num = this.Maximum - this.Minimum;
int i = 0;
// Draw each tick text
for (i = 0; i <= tickCount; i++)
{
text = Convert.ToString(Convert.ToInt32(this.Maximum) - Convert.ToInt32(this.Minimum + this.TickFrequency * i), 10);
formattedText = new FormattedText(text, CultureInfo.GetCultureInfo("en-us"), FlowDirection.RightToLeft, new Typeface("Verdana"), 16, Brushes.Black);
dc.DrawText(formattedText, new Point(0, (tickFrequencySize * i)));
}
}
}
now we get the following: http://s4.postimage.org/d0q6dpxvx/Correct.jpg
Hooray!
source to share