- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要创建一个带有两个拇指的 slider 控件 [range slider]。谁能给我以这种方式修改默认 slider 控件的想法?
最佳答案
我创建了一个带有两个 slider 的自定义 slider 控件。
此链接对我有帮助
http://blogs.u2u.be/diederik/post/2012/01/21/Building-C-custom-controls-in-WinRT-Metro.aspxMainPage.xaml:
<newslider:SimpleSlider x:Name="PriceSlider" Width="650" LowerValueChanged="PriceSlider_LowerValueChanged" UpperValueChanged="PriceSlider_UpperValueChanged"/>
MainPage.xaml.cs:
private void PriceSlider_UpperValueChanged(object sender, EventArgs e)
{
}
private void PriceSlider_LowerValueChanged(object sender, EventArgs e)
{
}
控制代码如下:
通用.xaml:
<Style TargetType="ctrl:RangeSliderSlider">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:SimpleSlider">
<StackPanel>
<Grid Height="15">
<Border Height="15"
VerticalAlignment="Stretch"
Background="DarkGray"/>
<Canvas Margin="0"
MinHeight="8">
<Rectangle x:Name="PART_Rectangle_Middle"
Height="15"
Fill="LightBlue" />
<Thumb x:Name="PART_Thumb_Lower"
Width="15"
Height="15" Background="White" />
<Thumb x:Name="PART_Thumb_Upper"
Width="15"
Height="15" Background="White" />
</Canvas>
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,0,-15,0">
<ItemsControl x:Name="PART_ItemsControl_RangeControl"
Canvas.ZIndex="1"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding Tag,ElementName=PART_ItemsControl_RangeControl}" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Text="|" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="Gray" FontSize="10"/>
<TextBlock Grid.Row="1" Foreground="Gray" VerticalAlignment="Center" Margin="{Binding RangeMargin}" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding RangeValue}" FontSize="12"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid x:Name="PART_LastMark_Grid" Width="{Binding Tag,ElementName=PART_ItemsControl_RangeControl}" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Text="|" Grid.Row="0" VerticalAlignment="Center" Margin="-4,0,0,0" HorizontalAlignment="Left" Foreground="Gray" FontSize="10"/>
<TextBlock x:Name="PART_Lastmark_TextBlock" Grid.Row="1" Margin="-4,0,0,0" Foreground="Gray" VerticalAlignment="Center" HorizontalAlignment="Left" TextAlignment="Left" FontSize="12"/>
</Grid>
</StackPanel>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
RangeSlider.cs:
using RangeSlider;
using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
[TemplatePart(Name = ThumbPartName_Upper, Type = typeof(Thumb))]
[TemplatePart(Name = ThumbPartNameLower, Type = typeof(Thumb))]
[TemplatePart(Name = RectanglePartName, Type = typeof(Rectangle))]
[TemplatePart(Name = RangeValueControl, Type = typeof(ItemsControl))]
[TemplatePart(Name = RangeLastMarkValue, Type = typeof(TextBlock))]
public class SimpleSlider : Control
{
private const string ThumbPartName_Upper = "PART_Thumb_Upper";
private const string RectanglePartName = "PART_Rectangle_Middle";
private const string ThumbPartNameLower = "PART_Thumb_Lower";
private const string RangeValueControl = "PART_ItemsControl_RangeControl";
private const string RangeLastMarkValue = "PART_Lastmark_TextBlock";
private Thumb _upperThumb;
private Thumb _lowerthumb;
private Rectangle _middleFillRectangle;
private ItemsControl _scaleValueControl;
private TextBlock _lastmarkTextblock;
private int _interval;
private double _sectionValue;
private double _interval_width;
public event EventHandler LowerValueChanged;
public event EventHandler UpperValueChanged;
#region Properties
private bool isThumbSelected = true;
public bool IsThumbSelected
{
get { return isThumbSelected; }
set { isThumbSelected = value; IsThumb_Selected = value; }
}
public static bool IsThumb_Selected { get; set; }
#endregion
#region Dependency Properties
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public double Maximum
{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public double LowerValue
{
get { return (double)GetValue(LowerValueProperty); }
set
{
SetValue(LowerValueProperty, value);
RangeEventArgs e = new RangeEventArgs() { NewValue = value };
if (LowerValueChanged != null)
LowerValueChanged(this, e);
}
}
public double UpperValue
{
get { return (double)GetValue(UpperValueProperty); }
set
{
SetValue(UpperValueProperty, value);
RangeEventArgs e = new RangeEventArgs() { NewValue = value };
if (UpperValueChanged != null)
UpperValueChanged(this, e);
}
}
// Using a DependencyProperty as the backing store for UpperValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UpperValueProperty =
DependencyProperty.Register("UpperValue", typeof(double), typeof(SimpleSlider), new PropertyMetadata(0.0, UpperValuePropertyChanged));
// Using a DependencyProperty as the backing store for LowerValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LowerValueProperty =
DependencyProperty.Register("LowerValue", typeof(double), typeof(SimpleSlider), new PropertyMetadata(0.0, LowerValuePropertyChanged));
// Using a DependencyProperty as the backing store for Minimum. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(SimpleSlider), new PropertyMetadata(0.0));
// Using a DependencyProperty as the backing store for Maximum. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(SimpleSlider), new PropertyMetadata(0.0));
// Using a DependencyProperty as the backing store for RangeCollection. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RangeCollectionProperty =
DependencyProperty.Register("RangeCollection", typeof(List<Range>), typeof(SimpleSlider), new PropertyMetadata(null));
public List<Range> RangeCollection
{
get { return (List<Range>)GetValue(RangeCollectionProperty); }
set { SetValue(RangeCollectionProperty, value); }
}
public double Division
{
get { return (double)GetValue(DivisionProperty); }
set { SetValue(DivisionProperty, value); }
}
// Using a DependencyProperty as the backing store for Division. This enables binding scale division width, etc...
public static readonly DependencyProperty DivisionProperty =
DependencyProperty.Register("Division", typeof(double), typeof(SimpleSlider), new PropertyMetadata(0));
public string LastMark
{
get { return (string)GetValue(LastMarkProperty); }
set { SetValue(LastMarkProperty, value); }
}
public static readonly DependencyProperty LastMarkProperty =
DependencyProperty.Register("LastMark", typeof(string), typeof(SimpleSlider), new PropertyMetadata(""));
public int MinimumInterval
{
get { return (int)GetValue(MinimumIntervalProperty); }
set { SetValue(MinimumIntervalProperty, value); }
}
// Using a DependencyProperty as the backing store for MinimumInterval. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MinimumIntervalProperty =
DependencyProperty.Register("MinimumInterval", typeof(int), typeof(SimpleSlider), new PropertyMetadata(5));
public int MaximumInteraval
{
get { return (int)GetValue(MaximumInteravalProperty); }
set { SetValue(MaximumInteravalProperty, value); }
}
// Using a DependencyProperty as the backing store for MaximumInteraval. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaximumInteravalProperty =
DependencyProperty.Register("MaximumInteraval", typeof(int), typeof(SimpleSlider), new PropertyMetadata(15));
#endregion
/// <summary>
/// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate"/>.
/// </summary>
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
this._upperThumb = this.GetTemplateChild(ThumbPartName_Upper) as Thumb;
if (this._upperThumb != null)
{
this._upperThumb.DragDelta += this.Thumb_DragDelta;
}
this._lowerthumb = this.GetTemplateChild(ThumbPartNameLower) as Thumb;
if (_lowerthumb != null)
{
this._lowerthumb.DragDelta += this.Thumb1_DragDelta;
}
this._middleFillRectangle = this.GetTemplateChild(RectanglePartName) as Rectangle;
this._scaleValueControl = this.GetTemplateChild(RangeValueControl) as ItemsControl;
this._lastmarkTextblock = this.GetTemplateChild(RangeLastMarkValue) as TextBlock;
this.SizeChanged += new SizeChangedEventHandler(SimpleSlider_SizeChanged);
}
/// <summary>
/// Method for displying values in the range slider
/// </summary>
public void PopulateScaleValues()
{
_sectionValue = Minimum;
bool isDivFound = false;
for (int i = MaximumInteraval; i >= MinimumInterval; i--)
{
if (!isDivFound)
{
if (0 == Math.IEEERemainder(Maximum, i))
{
_interval = i;
isDivFound = true;
continue;
}
}
}
_interval_width = Maximum / _interval;
var totalSize = this.ActualWidth;
Division = totalSize / _interval;
this._scaleValueControl.Tag = Division;
if (RangeCollection == null)
RangeCollection = new List<Range>();
RangeCollection.Add(new Range { RangeValue = _sectionValue });
for (int i = 0; i < _interval; i++)
{
_sectionValue = _sectionValue + _interval_width;
RangeCollection.Add(new Range { RangeValue = _sectionValue });
}
this._scaleValueControl.ItemsSource = RangeCollection;
LastMark = (_sectionValue + _interval_width).ToString();
this._lastmarkTextblock.Text = RangeCollection[_interval].RangeValue.ToString();
}
/// <summary>
/// Called when size changed.
/// </summary>
private void SimpleSlider_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.NewSize.Width != e.PreviousSize.Width)
{
//this.UpdateControls();
//this.UpdateControls1();
//PopulateScaleValues();
}
}
/// <summary>
/// Called when value changed.
/// </summary>
private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
// Simple version: no coercion involved.
var customSlider = (SimpleSlider)dependencyObject;
if (IsThumb_Selected)
{
customSlider.UpperValue = Convert.ToDouble(e.NewValue);
}
else
{
customSlider.LowerValue = Convert.ToDouble(e.NewValue);
}
}
/// <summary>
/// Called when lower value changed
/// </summary>
private static void LowerValuePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var customSlider = (SimpleSlider)dependencyObject;
customSlider.UpperValue = Math.Max(customSlider.UpperValue, customSlider.LowerValue);
customSlider.UpdateControls1();
}
/// <summary>
/// Called When Upper value changed
/// </summary>
private static void UpperValuePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var customSlider = (SimpleSlider)dependencyObject;
customSlider.LowerValue = Math.Min(customSlider.UpperValue, customSlider.LowerValue);
customSlider.UpdateControls();
}
/// <summary>
/// Handles the DragDelta event of the Thumb control.
/// </summary>
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
IsThumbSelected = true;
this._lowerthumb.Visibility = Visibility.Visible;
this._upperThumb.Visibility = Visibility.Visible;
var pixelDiff = e.HorizontalChange;
var currentLeft = Canvas.GetLeft(this._upperThumb);
// trying to drag too far left
if ((currentLeft + pixelDiff) < 0)
{
this.UpperValue = 0;
}
// trying to drag too far right
else if ((currentLeft + pixelDiff + this._upperThumb.ActualWidth) > this.ActualWidth)
{
this.UpperValue = this.Maximum;
}
else
{
var totalSize = this.ActualWidth;
var ratioDiff = pixelDiff / totalSize;
var rangeSize = this.Maximum - this.Minimum;
var rangeDiff = rangeSize * ratioDiff;
this.UpperValue += rangeDiff;
}
if (this.LowerValue == this.UpperValue && e.HorizontalChange < 0)
{
this._lowerthumb.Visibility = Visibility.Visible;
this._upperThumb.Visibility = Visibility.Collapsed;
}
if (this.LowerValue == this.Minimum && this.LowerValue == this.UpperValue)
{
this._lowerthumb.Visibility = Visibility.Collapsed;
this._upperThumb.Visibility = Visibility.Visible;
}
}
/// <summary>
/// Handles the DragDelta event of the Thumb control.
/// </summary>
private void Thumb1_DragDelta(object sender, DragDeltaEventArgs e)
{
this._lowerthumb.Visibility = Visibility.Visible;
this._upperThumb.Visibility = Visibility.Visible;
IsThumbSelected = false;
var pixelDiff = e.HorizontalChange;
var currentLeft = Canvas.GetLeft(this._lowerthumb);
// trying to drag too far left
if ((currentLeft + pixelDiff) < 0)
{
this.LowerValue = 0;
}
// trying to drag too far right
else if ((currentLeft + pixelDiff + this._lowerthumb.ActualWidth) > this.ActualWidth)
{
this.LowerValue = this.Maximum;
}
else
{
var totalSize = this.ActualWidth;
var ratioDiff = pixelDiff / totalSize;
var rangeSize = this.Maximum - this.Minimum;
var rangeDiff = rangeSize * ratioDiff;
this.LowerValue += rangeDiff;
}
if (this.LowerValue == this.UpperValue && e.HorizontalChange > 0)
{
this._lowerthumb.Visibility = Visibility.Collapsed;
this._upperThumb.Visibility = Visibility.Visible;
}
if (this.LowerValue == this.Maximum && this.LowerValue==this.UpperValue)
{
this._lowerthumb.Visibility = Visibility.Visible;
this._upperThumb.Visibility = Visibility.Collapsed;
}
}
/// <summary>
/// Updates the controls.
/// </summary>
public void UpdateControls()
{
double halfTheThumbWith = 0;
if (this._upperThumb != null)
{
halfTheThumbWith = this._upperThumb.ActualWidth / 2;
}
double totalSize = this.ActualWidth - halfTheThumbWith * 2;
double ratio = totalSize / (this.Maximum - this.Minimum);
if (this._upperThumb != null)
{
Canvas.SetLeft(this._upperThumb, ratio * this.UpperValue);
}
if (this._middleFillRectangle != null)
{
Canvas.SetLeft(this._middleFillRectangle, ratio * this.LowerValue);
this._middleFillRectangle.Width = ratio * (this.UpperValue - this.LowerValue) + halfTheThumbWith;
}
}
/// <summary>
/// Updates the controls.
/// </summary>
public void UpdateControls1()
{
double halfTheThumbWith = 0;
if (this._lowerthumb != null)
{
halfTheThumbWith = this._upperThumb.ActualWidth / 2;
}
double totalSize = this.ActualWidth - halfTheThumbWith * 2;
double ratio = totalSize / (this.Maximum - this.Minimum);
if (this._lowerthumb != null)
{
Canvas.SetLeft(this._lowerthumb, ratio * this.LowerValue);
}
if (this._middleFillRectangle != null)
{
Canvas.SetLeft(this._middleFillRectangle, ratio * this.LowerValue);
this._middleFillRectangle.Width = ratio * (this.UpperValue - this.LowerValue) + halfTheThumbWith;
}
}
}
Range.cs 模型:
public class Range
{
public double RangeValue { get; set; }
public Thickness RangeMargin
{
get
{
if (RangeValue.ToString().Length == 1)
{
return new Thickness(-1, 0, -1, 0);
}
else if (RangeValue.ToString().Length == 2)
{
return new Thickness(-5, 0, -5, 0);
}
else if (RangeValue.ToString().Length == 3)
{
return new Thickness(-7, 0, -7, 0);
}
else if (RangeValue.ToString().Length == 4)
{
return new Thickness(-9, 0, -9, 0);
}
else
return new Thickness(-1, 0, -1, 0);
}
}
}
RangeEventArgs.cs:
public class RangeEventArgs :EventArgs
{
public double NewValue { get; set; }
}
关于c# - c#xaml 中的范围 slider 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13513046/
我不能解决这个问题。和标题说的差不多…… 如果其他两个范围/列中有“否”,我如何获得范围或列的平均值? 换句话说,我想计算 A 列的平均值,并且我有两列询问是/否问题(B 列和 C 列)。我只希望 B
我知道 python 2to3 将所有 xrange 更改为 range 我没有发现任何问题。我的问题是关于它如何将 range(...) 更改为 list(range(...)) :它是愚蠢的,只是
我有一个 Primefaces JSF 项目,并且我的 Bean 注释有以下内容: @Named("reportTabBean") @SessionScoped public class Report
在 rails3 中,我在模型中制作了相同的范围。例如 class Common ?" , at) } end 我想将公共(public)范围拆分为 lib 中的模块。所以我试试这个。 module
我需要在另一个 View 范围 bean 中使用保存在 View 范围 bean 中的一些数据。 @ManagedBean @ViewScoped public class Attivita impl
为什么下面的代码输出4?谁能给我推荐一篇好文章来深入学习 javascript 范围。 这段代码返回4,但我不明白为什么? (function f(){ return f(); functio
我有一个与此结构类似的脚本 $(function(){ var someVariable; function doSomething(){ //here } $('#som
我刚刚开始学习 Jquery,但这些示例对我帮助不大...... 现在,以下代码发生的情况是,我有 4 个表单,我使用每个表单的链接在它们之间进行切换。但我不知道如何在第一个函数中获取变量“postO
为什么当我这样做时: function Dog(){ this.firstName = 'scrappy'; } Dog.firstName 未定义? 但是我可以这样做: Dog.firstNa
我想打印文本文件 text.txt 的选定部分,其中包含: tickme 1.1(no.3) lesson1-bases lesson2-advancedfurther para:using the
我正在编写一些 JavaScript 代码。我对这个关键字有点困惑。如何在 dataReceivedHandler 函数中访问 logger 变量? MyClass: { logger: nu
我有这个代码: Public Sub test() Dim Tgt As Range Set Tgt = Range("A1") End Sub 我想更改当前为“A1”的 Tgt 的引
我正忙于此工作,以为我会把它放在我们那里。 该数字必须是最多3个单位和最多5个小数位的数字,等等。 有效的 999.99999 99.9 9 0.99999 0 无效的 -0.1 999.123456
覆盖代码时: @Override public void open(ExecutionContext executionContext) { super.open(executio
我想使用 preg_match 来匹配数字 1 - 21。我如何使用 preg_match 来做到这一点?如果数字大于 21,我不想匹配任何东西。 example preg_match('([0-9]
根据docs range函数有四种形式: (range) 0 - 无穷大 (range end) 0 - 结束 (range start end)开始 - 结束 (range start end st
我知道有一个UISlider,但是有人已经制作了RangeSlider(用两个拇指吗?)或者知道如何扩展 uislider? 最佳答案 我认为你不能直接扩展 UISlider,你可能需要扩展 UICo
我正在尝试将范围转换为列表。 nums = [] for x in range (9000, 9004): nums.append(x) print nums 输出 [9000] [9
请注意:此问题是由于在运行我的修饰方法时使用了GraphQL解析器。这意味着this的范围为undefined。但是,该问题的基础知识对于装饰者遇到问题的任何人都是有用的。 这是我想使用的基本装饰器(
我正在尝试创建一个工具来从网页上抓取信息(是的,我有权限)。 到目前为止,我一直在使用 Node.js 结合 requests 和 Cheerio 来拉取页面,然后根据 CSS 选择器查找信息。我已经
我是一名优秀的程序员,十分优秀!