【问题标题】:Universal Windows (UWP) Range Slider通用 Windows (UWP) 范围滑块
【发布时间】:2016-08-01 10:47:57
【问题描述】:

我想在 UWP 中创建 范围滑块。我没有找到任何例子。只有单个滑块,但我希望它像

有人知道我该怎么做吗?请帮帮我。

【问题讨论】:

    标签: c# uwp win-universal-app uwp-xaml rangeslider


    【解决方案1】:

    要在 UWP 中创建范围滑块,我们可以创建自定义控件或使用UserControl。这里我以UserControl为例:

    首先,我在我的项目中添加一个名为“MyRangeSlider”的 UserControl。

    在 XAML 中:

    <UserControl x:Class="UWP.MyRangeSlider"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:local="using:UWP"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 d:DesignHeight="300"
                 d:DesignWidth="400"
                 mc:Ignorable="d">
    
        <Grid Height="32" Margin="8,0">
            <Grid.Resources>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Thumb">
                                <Ellipse Width="32"
                                         Height="32"
                                         Fill="White"
                                         RenderTransformOrigin="0.5 0.5"
                                         Stroke="Gray"
                                         StrokeThickness="1">
                                    <Ellipse.RenderTransform>
                                        <TranslateTransform X="-16" />
                                    </Ellipse.RenderTransform>
                                </Ellipse>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Grid.Resources>
            <Rectangle Height="16"
                       Margin="8,0"
                       Fill="#FFD5D5D5"
                       RadiusX="5"
                       RadiusY="5" />
            <Canvas x:Name="ContainerCanvas" Margin="8,0" SizeChanged="ContainerCanvas_SizeChanged">
                <Thumb x:Name="MinThumb" DragCompleted="MinThumb_DragCompleted" DragDelta="MinThumb_DragDelta" />
                <Thumb x:Name="MaxThumb" DragCompleted="MaxThumb_DragCompleted" DragDelta="MaxThumb_DragDelta" />
                <Rectangle x:Name="ActiveRectangle"
                           Canvas.Top="8"
                           Height="16"
                           Canvas.ZIndex="-1"
                           Fill="#FF69A0CC" />
            </Canvas>
        </Grid>
    </UserControl>
    

    在其代码隐藏中:

    public sealed partial class MyRangeSlider : UserControl
    {
        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 RangeMin
        {
            get { return (double)GetValue(RangeMinProperty); }
            set { SetValue(RangeMinProperty, value); }
        }
    
        public double RangeMax
        {
            get { return (double)GetValue(RangeMaxProperty); }
            set { SetValue(RangeMaxProperty, value); }
        }
    
        public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(MyRangeSlider), new PropertyMetadata(0.0));
    
        public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(MyRangeSlider), new PropertyMetadata(1.0));
    
        public static readonly DependencyProperty RangeMinProperty = DependencyProperty.Register("RangeMin", typeof(double), typeof(MyRangeSlider), new PropertyMetadata(0.0, OnRangeMinPropertyChanged));
    
        public static readonly DependencyProperty RangeMaxProperty = DependencyProperty.Register("RangeMax", typeof(double), typeof(MyRangeSlider), new PropertyMetadata(1.0, OnRangeMaxPropertyChanged));
    
        public MyRangeSlider()
        {
            this.InitializeComponent();
        }
    
        private static void OnRangeMinPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var slider = (MyRangeSlider)d;
            var newValue = (double)e.NewValue;
    
            if (newValue < slider.Minimum)
            {
                slider.RangeMin = slider.Minimum;
            }
            else if (newValue > slider.Maximum)
            {
                slider.RangeMin = slider.Maximum;
            }
            else
            {
                slider.RangeMin = newValue;
            }
    
            if (slider.RangeMin > slider.RangeMax)
            {
                slider.RangeMax = slider.RangeMin;
            }
    
            slider.UpdateMinThumb(slider.RangeMin);
        }
    
        private static void OnRangeMaxPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var slider = (MyRangeSlider)d;
            var newValue = (double)e.NewValue;
    
            if (newValue < slider.Minimum)
            {
                slider.RangeMax = slider.Minimum;
            }
            else if (newValue > slider.Maximum)
            {
                slider.RangeMax = slider.Maximum;
            }
            else
            {
                slider.RangeMax = newValue;
            }
    
            if (slider.RangeMax < slider.RangeMin)
            {
                slider.RangeMin = slider.RangeMax;
            }
    
            slider.UpdateMaxThumb(slider.RangeMax);
        }
    
        public void UpdateMinThumb(double min, bool update = false)
        {
            if (ContainerCanvas != null)
            {
                if (update || !MinThumb.IsDragging)
                {
                    var relativeLeft = ((min - Minimum) / (Maximum - Minimum)) * ContainerCanvas.ActualWidth;
    
                    Canvas.SetLeft(MinThumb, relativeLeft);
                    Canvas.SetLeft(ActiveRectangle, relativeLeft);
    
                    ActiveRectangle.Width = (RangeMax - min) / (Maximum - Minimum) * ContainerCanvas.ActualWidth;
                }
            }
        }
    
        public void UpdateMaxThumb(double max, bool update = false)
        {
            if (ContainerCanvas != null)
            {
                if (update || !MaxThumb.IsDragging)
                {
                    var relativeRight = (max - Minimum) / (Maximum - Minimum) * ContainerCanvas.ActualWidth;
    
                    Canvas.SetLeft(MaxThumb, relativeRight);
    
                    ActiveRectangle.Width = (max - RangeMin) / (Maximum - Minimum) * ContainerCanvas.ActualWidth;
                }
            }
        }
    
        private void ContainerCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var relativeLeft = ((RangeMin - Minimum) / (Maximum - Minimum)) * ContainerCanvas.ActualWidth;
            var relativeRight = (RangeMax - Minimum) / (Maximum - Minimum) * ContainerCanvas.ActualWidth;
    
            Canvas.SetLeft(MinThumb, relativeLeft);
            Canvas.SetLeft(ActiveRectangle, relativeLeft);
            Canvas.SetLeft(MaxThumb, relativeRight);
    
            ActiveRectangle.Width = (RangeMax - RangeMin) / (Maximum - Minimum) * ContainerCanvas.ActualWidth;
        }
    
        private void MinThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            var min = DragThumb(MinThumb, 0, Canvas.GetLeft(MaxThumb), e.HorizontalChange);
            UpdateMinThumb(min, true);
            RangeMin = Math.Round(min);
        }
    
        private void MaxThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            var max = DragThumb(MaxThumb, Canvas.GetLeft(MinThumb), ContainerCanvas.ActualWidth, e.HorizontalChange);
            UpdateMaxThumb(max, true);
            RangeMax = Math.Round(max);
        }
    
        private double DragThumb(Thumb thumb, double min, double max, double offset)
        {
            var currentPos = Canvas.GetLeft(thumb);
            var nextPos = currentPos + offset;
    
            nextPos = Math.Max(min, nextPos);
            nextPos = Math.Min(max, nextPos);
    
            return (Minimum + (nextPos / ContainerCanvas.ActualWidth) * (Maximum - Minimum));
        }
    
        private void MinThumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            UpdateMinThumb(RangeMin);
            Canvas.SetZIndex(MinThumb, 10);
            Canvas.SetZIndex(MaxThumb, 0);
        }
    
        private void MaxThumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            UpdateMaxThumb(RangeMax);
            Canvas.SetZIndex(MinThumb, 0);
            Canvas.SetZIndex(MaxThumb, 10);
        }
    }
    

    然后我可以使用MyRangeSlider,如下所示:

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="auto" />
        </Grid.ColumnDefinitions>
        <TextBox HorizontalAlignment="Center" FontSize="20" Text="{Binding RangeMin, ElementName=RangeSlider, Mode=TwoWay}" />
        <local:MyRangeSlider x:Name="RangeSlider"
                             Grid.Column="1"
                             Maximum="100"
                             Minimum="0"
                             RangeMax="80"
                             RangeMin="20" />
        <TextBox Grid.Column="2"
                 HorizontalAlignment="Center"
                 FontSize="20"
                 Text="{Binding RangeMax,
                                ElementName=RangeSlider,
                                Mode=TwoWay}" />
    </Grid>
    

    它看起来像:
    这是一个简单的示例,您可以对其进行编辑以满足您的要求。而如果要创建自定义控件,可以参考Building a custom control using XAML and C#。虽然这篇文章是针对Windows 8 XAML平台的,但是UWP也是一样的。

    【讨论】:

      猜你喜欢
      • 2018-11-21
      • 2011-02-10
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2014-09-29
      相关资源
      最近更新 更多