Как найти большой палец ползунка, чтобы установить его ширину

#wpf #slider #rangeslider

#wpf #ползунок #rangeslider

Вопрос:

Я создаю «ползунок диапазона» из трех элементов управления ползунком, наложенных друг на друга. Основная идея взята отсюда, в которой используются два ползунка.

http://www.thejoyofcode.com/Creating_a_Range_Slider_in_WPF_and_other_cool_tips_and_tricks_for_UserControls_.aspx

Я добавляю третий ползунок, большой палец которого заполнит пространство между большими пальцами другого ползунка. Пользователь сможет перетащить этот центральный большой палец, чтобы переместить два конца и поддерживать постоянное расстояние между двумя концами.

XAML — это просто три ползунка. Секрет того, как заставить его красиво накладываться, заключается в использовании шаблона управления (здесь не воспроизводится. Вы можете найти его по указанному выше URL).

 <Grid VerticalAlignment="Top">
    <Border BorderThickness="0,1,0,0" BorderBrush="Green" VerticalAlignment="Center" Height="1" 
            Margin="5,0,5,0"/>

    <Slider x:Name="LowerSlider"
            Minimum="{Binding ElementName=root, Path=Minimum}"
            Maximum="{Binding ElementName=root, Path=Maximum}"
            Value="{Binding ElementName=root, Path=LowerValue, Mode=TwoWay}"
            Margin="0,0,0,0"
            Template="{StaticResource simpleSlider}"
            />
    
    <Slider x:Name="MiddleSlider"
            Minimum="{Binding ElementName=root, Path=Minimum}"
            Maximum="{Binding ElementName=root, Path=Maximum}"
            Value="{Binding ElementName=root, Path=MiddleValue, Mode=TwoWay}"
            Margin="10,0,0,0"
            Template="{StaticResource simpleSlider}"
            >
   </Slider>
    
    <Slider x:Name="UpperSlider"
            Minimum="{Binding ElementName=root, Path=Minimum}"
            Maximum="{Binding ElementName=root, Path=Maximum}"
            Value="{Binding ElementName=root, Path=UpperValue, Mode=TwoWay}"
            Margin="20,0,0,0"
            Template="{StaticResource simpleSlider}"
            />
</Grid>
  

При перетаскивании любого внешнего большого пальца мне нужно изменить размер центрального большого пальца, чтобы заполнить пространство между двумя концевыми большими пальцами.

В приведенном коде я могу уловить движение большого пальца и могу найти средний элемент управления ползунком, но я не могу понять, как программно добраться до большого пальца среднего ползунка, чтобы я мог изменить его размер, чтобы заполнить пространство между двумя внешними большими пальцами.

 private void UpperSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
         Slider slider= (Slider) this.FindName("MiddleSlider");
        // how to find the middleSlider thumb so I can set
        // it's width to fill the space between the outer thumbs
    }
  

Ответ №1:

Это должно сделать это:

 var track = (Track)slider.Template.FindName("PART_Track", slider);
var thumb = track.Thumb;
thumb.Width = fittingWidth;
  

(Кстати, я бы не стал делать это таким образом, я бы применил MultiBinding к двум другим ползункам и конвертеру, который вычисляет ширину на основе этого)

Комментарии:

1. Спасибо @H.B. Именно этой концепции мне не хватало. Просто для завершения примера для будущих читателей, большой палец также является шаблонным, поэтому мне нужно было восстановить его представление таким же образом.

2. Я думал, вы хотели установить только ширину? Это должно быть возможно без погружения в шаблон большого пальца. В любом случае, если это ответило на ваш вопрос, вы можете принять его, указав галочку слева от моего ответа.

3. Я просто хочу добавить, что вычисление ширины среднего большого пальца для заполнения пространства между двумя внешними большими пальцами сложно, потому что по мере увеличения ширины большого пальца количество пикселей, которые большой палец перемещает влево и вправо, уменьшается. Это потому, что ползунок останавливает большой палец, когда левый край большого пальца достигает левого края элемента управления. Когда большой палец шире, центр большого пальца смещается. Решение состоит в том, чтобы вычислить местоположение в пикселях двух внешних больших пальцев, затем вычислить slider.Value, который расположит средний палец между двумя внешними большими пальцами.

4. Track находится в System.Windows.Controls.Primitives пространстве имен.

Ответ №2:

     private void UpperSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        Slider slider = (Slider) FindName("MiddleSlider");
        Track track = slider.Template.FindName("PART_Track", slider) as Track;
        if (track != null)
        {
            Rectangle thumbRectangle = track.Thumb.Template.FindName("Rect1", track.Thumb) as Rectangle;
            if (thumbRectangle != null)
            {
                thumbRectangle.Width = CalculateWidth();
            }
        }
    }