Vertical slider with labels on the ticker
So, I can now answer my own question and maybe help someone in the future who will try to acomplish the same. Like I said in the comment of my own question, just later I realized I could go to the msdn and get the proper vertical slider template instead of trying to adapt the horizontal one.
My current XAML is now:
<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 do make some small changes to my class, since now I'm using a proper 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's 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)));
}
}
}
getting now the following: http://s4.postimage.org/d0q6dpxvx/Correct.jpg
Cheers!
Related videos on Youtube
Santux
I'm a software engineer with major interests in ASP.NET (C#, DotNetNuke, WPF, SQL Server) and Mobile (Android).
Updated on September 14, 2022Comments
-
Santux over 1 year
I'm currently trying to get a custom vertical slider with a ticker as well as labels in those tickers with the corresponding values. I already found online some interesting code for a horizontal slider that I'm now using in my solution and goes as follows:
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>
With MyTickBar being 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's 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 fine with a horizontal slider, but as I pretend a vertical one I tried 2 different solutions with no success. First, was to make a similar XAML for a vertical slider, but as I'm quite new to WPF, I couldn't achieve the intended solution (I basically changed the row and height properties to column and with, but is probably a bit more complex than that). And my second attempt was using a
<Slider.LayoutTransform> <RotateTransform Angle="270"/> </Slider.LayoutTransform>
on the pretended slider, getting a slider with the labels in the incorrect position, like the following image illustrates: http://s22.postimage.org/sophl10wh/Incorrect.jpg
I tried to apply a rotation to the DrawingContext of MyTicker but that rotates the entire ticker, instead of the labels with the values. So, my question is how can I obtain the pretend solution? Either through the necessary changes to a new XAML for a custom vertical slider, or just rotating the labels in the second solution.
-
Zev Spitz almost 11 yearsI am trying to implement something similar. What XAML did you use for the slider itself?
-
Santux almost 11 yearsYou should use the slider control template present in msdn.microsoft.com/en-us/library/ms753256(v=vs.85).aspx and I replaced one of the tickbars with: <local:MyTickBarVertical x:Name="TopTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" SnapsToDevicePixels="True" Margin="0,0,0,20" Placement="Top" Width="4"/> where you define a class MyTickBarVertical : TickBar like the one I have in the answer.
-
Zev Spitz almost 11 yearsAnd then what:
<Slider Template={StaticResource VerticalSlider} />
and what else? -
Santux almost 11 yearsI used it as a style. In the App.xaml I defined <Style x:Key="MyCustomStyleForSliderVertical" TargetType="{x:Type Slider}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Slider}"> (...) and in your window or control you just apply that style to the control such as Style="{StaticResource MyCustomStyleForSliderVertical}"