2016-04-11 14 views

答えて

8

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> 

そして、それがどのように見えるが:
enter image description here これは簡単なサンプルで、要件に合わせて編集することができます。カスタムコントロールを作成する場合は、Building a custom control using XAML and C#を参照してください。この記事はWindows 8 XAMLプラットフォームですが、UWPは同じですが

関連する問題