WPF 多滑塊Slider簡單實現(MultiRangeSlider)
WPF中的MultiRangeSlider,網上有商業的,有開源的,找了幾個都不太理想,那就自己寫
一個吧,給大家提供點思路。
WPF中的Slider,看他的模板那就很複雜,如果想弄一個可以自定義樣式的MultiRangeSlider
那就得花大時間好好弄,粗略的想MultiRangeSlider不就是幾個滑塊(Thumb),加幾個矩形麼,
一個滑塊對應兩個矩形,滑塊移動的時候,不就兩邊的矩形的寬度的變化麼,矩形我們只想
關注寬度變化,不想再去調整他的其實位置,用什麼容器來裝矩形呢,StackPanel,裡面的物件
總是首尾相連的嘛,可是要使Thumb能夠水平移動,在StackPanel中顯示不合適,那就放到Canvas
中,然後把這兩個容器使用Grid疊在一起,Canvas在上,就是下面這個樣子
<Grid>
<StackPanel Margin="15,0,15,0"
x:Name="RangeContainer"
Orientation="Horizontal">
</StackPanel>
<Canvas x:Name="ThumbContainer">
</Canvas>
</Grid>
滑塊為了好看,也做了樣式修改
<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的資料結構
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不就左邊矩形的寬度麼。在把滑塊和左右兩邊的矩形關聯起來,因為矩形的拖動事件
需要實時去改變兩邊的矩形的寬度。
我還是直接上程式碼吧,講這麼多你們也不一定清楚,哎。