0%

WPF MultiRangeSlider 简单实现 - UncleNull - 博客园

Excerpt

WPF 多滑块Slider简单实现(MultiRangeSlider) WPF中的MultiRangeSlider,网上有商业的,有开源的,找了几个都不太理想,那就自己写 一个吧,给大家提供点思路。 WPF中的Slider,看他的模板那就很复杂,如果想弄一个可以自定义样式的MultiRangeSli


WPF 多滑块Slider简单实现(MultiRangeSlider)

WPF中的MultiRangeSlider,网上有商业的,有开源的,找了几个都不太理想,那就自己写
一个吧,给大家提供点思路。

WPF中的Slider,看他的模板那就很复杂,如果想弄一个可以自定义样式的MultiRangeSlider
那就得花大时间好好弄,粗略的想MultiRangeSlider不就是几个滑块(Thumb),加几个矩形么,
一个滑块对应两个矩形,滑块移动的时候,不就两边的矩形的宽度的变化么,矩形我们只想
关注宽度变化,不想再去调整他的其实位置,用什么容器来装矩形呢,StackPanel,里面的对象
总是首尾相连的嘛,可是要使Thumb能够水平移动,在StackPanel中显示不合适,那就放到Canvas
中,然后把这两个容器使用Grid叠在一起,Canvas在上,就是下面这个样子

1
<Grid> <StackPanel Margin="15,0,15,0" x:Name="RangeContainer" Orientation="Horizontal"> </StackPanel> <Canvas x:Name="ThumbContainer"> </Canvas> </Grid>

滑块为了好看,也做了样式修改

1
<Style TargetType="local:ThumbEx"> <Setter Property="Width" Value="30"></Setter> <Setter Property="Height" Value="150"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Thumb"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="40" /> <RowDefinition /> <RowDefinition Height="40" /> </Grid.RowDefinitions> <StackPanel> <Rectangle SnapsToDevicePixels="True" Height="30" StrokeThickness="0" Stroke="LightGray" Fill="LightGray"></Rectangle> <Path Fill="LightGray" Stroke="LightGray" StrokeThickness="1" Data="M0,0 L30,0 L15,10z"> </Path> </StackPanel> <Path Grid.Row="1" Data="M15,0 L15,110" Fill="Black" Stroke="Black" StrokeThickness="1"></Path> <StackPanel Grid.Row="2"> <Path Fill="LightGray" StrokeThickness="1" Stroke="LightGray" Data="M15,0 L0,10 L30,10z"> </Path> <Rectangle Height="30" StrokeThickness="0" Stroke="LightGray" Fill="LightGray"></Rectangle> </StackPanel> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>

为了简便,我用了UserControl来实现这个控件,当然得支持各种数据Binding啊,对于这个控件来说,
我不需要知道外面是什么样的数据结构,我只需要知道我要展现多滑块需要哪些数据就行,
所以得有一个描述Range的数据结构

1
public class RangeItem { #region 字段 private double _from; private double _to; private string _name; private double _maxDuration; private bool _isStatic; private double _duration; #endregion #region 属性 public double From { get { return _from; } set { _from = value; } } public double To { get { return _to; } set { _to = value; } } /// <summary> /// 是否静止 /// </summary> public bool IsStatic { get { return _isStatic; } set { _isStatic = value; } } public double Duration { get { return _duration; } set { _duration = value; } } public double MaxDuration { get { return _maxDuration; } set { _maxDuration = value; } } #endregion } 重要的属性有From(起始值),To(结束值),MaxDuration(总长),

根据这一个数据,我们就能生成一个矩形。整个Slider的宽度是固定的,所以就可以根据
(To-From)/MaxDuration*Slider长度,就能计算出这个矩形的宽度,直接加入StackPanel就
行。
矩形加进去了,现在加滑块,因为滑块是在Canvas中的,所以他需要确切知道Canvas.Left附加
属性,这个Left不就左边矩形的宽度么。在把滑块和左右两边的矩形关联起来,因为矩形的拖动事件
需要实时去改变两边的矩形的宽度。
我还是直接上代码吧,讲这么多你们也不一定清楚,哎。

pic

WPF MultiRangeSlider