垂直滑块带有标签的刻度线

4

我目前正在尝试制作一个自定义垂直滑块,其中包括一个滚动文本和相应值的标签。我已经在网上找到了一些有趣的水平滑块代码,并将其用于我的解决方案中,如下所示:

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>

假设MyTickBar是一个被定义为以下类:

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));
        }
    }
}

这在水平滑块上很好用,但当我尝试使用垂直滑块时,我尝试了两种不同的解决方案都没有成功。第一种是为垂直滑块编写类似的XAML代码,但由于我对WPF比较陌生,无法达到预期的效果(基本上只是将行和高度属性更改为列和宽度,但可能要更加复杂)。我的第二次尝试是使用

<Slider.LayoutTransform>
            <RotateTransform Angle="270"/>
        </Slider.LayoutTransform>

在假装的滑块上,标签位置不正确,如下图所示:http://s22.postimage.org/sophl10wh/Incorrect.jpg 我尝试对MyTicker的DrawingContext应用旋转,但这会旋转整个滑块,而不是标签和值。所以,我的问题是如何获得假装的解决方案?可以通过对自定义垂直滑块的新XAML进行必要的更改,或者在第二种解决方案中仅旋转标签来实现。

我刚意识到自己有点(实际上是很)愚蠢,因为我可能可以从msdn获取垂直滑块的滑块控件模板示例,所以我现在会尝试一下 ;) - Santux
1个回答

8
所以,我现在可以回答自己的问题,并帮助将来尝试实现相同目标的人。就像我在自己的问题评论中所说的那样,后来我意识到我可以去MSDN获取合适的垂直滑动条模板,而不是试图调整水平滑动条。

我的当前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>

现在我正在使用适合的垂直滑块,因此我需要对我的类进行一些小改动:

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)));
        }
    }
}

现在收到以下内容:http://s4.postimage.org/d0q6dpxvx/Correct.jpg。祝贺!

1
我正在尝试实现类似的功能。您在滑块本身上使用了哪个XAML? - Zev Spitz
你应该使用http://msdn.microsoft.com/en-us/library/ms753256(v=vs.85).aspx中提供的滑块控件模板,我用以下代码替换了其中一个刻度条:<local:MyTickBarVertical x:Name="TopTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" SnapsToDevicePixels="True" Margin="0,0,0,20" Placement="Top" Width="4"/>。在这里,你需要定义一个类MyTickBarVertical:TickBar,就像我在答案中提到的那样。 - Santux
1
然后呢:<Slider Template={StaticResource VerticalSlider} /> 还有什么? - Zev Spitz
1
我将其用作样式。在App.xaml中,我定义了以下内容: <Style x:Key="MyCustomStyleForSliderVertical" TargetType="{x:Type Slider}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Slider}"> (...)在您的窗口或控件中,您只需将该样式应用于控件,例如 Style="{StaticResource MyCustomStyleForSliderVertical}" - Santux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接