C #: Как совместить TrackBar с ProgressBar - PullRequest
1 голос
/ 20 сентября 2009

Есть ли достаточно простой способ объединить трекбар с индикатором выполнения? Что бы я хотел сделать, чтобы индикатор выполнения отображался на трекбар только при нажатии кнопки. Это в основном для целей обучения, но было бы неплохо узнать, как использовать его на практике.

Заранее спасибо.

[править] Как это. http://www.java2s.com/Tutorial/VB/0260__GUI/LinkProgressBarwithaTrackBar.htm

Но внутри друг друга или вместе, а не рядом друг с другом.

Ответы [ 2 ]

2 голосов
/ 20 сентября 2009

Не совсем точно, что вы имеете в виду, но вы можете поместить TrackBar и ProgressBar в один пользовательский элемент управления UserControl (например, один над другим).

Обновление : поскольку вы хотите, чтобы они были объединены вместо одного другого, лучше всего просто написать собственный UserControl с нуля.

Обновление 2 : Нажмите здесь , чтобы увидеть приложение с простым UserControl, объединяющим концепции TrackBar и ProgressBar (переместите ползунок, чтобы изменить значение панели треков, и щелкните Кнопка «Показать прогресс», чтобы показать, как индикатор выполнения перемещается от нуля до места, где находится большой палец трек-бара). Нажмите здесь , чтобы загрузить исходный код.

0 голосов
/ 17 мая 2017

У меня есть решение. Это создает индикатор выполнения, который указывает, насколько заполнен «контейнер» с ползунком ползунка, наложенным сверху. Пользователь может перемещать ползунок внутри индикатора выполнения, но только до его текущего значения.

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

Шаг 1: Определите стиль для ползунка и добавьте индикатор выполнения. Поместите его в тот же визуал (та же ячейка сетки), что и большой палец. Поместите его перед большим пальцем, чтобы он оказался под ним:

<ControlTemplate x:Key="HorizontalProgressSlider" TargetType="{x:Type Slider}">
    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TickBar x:Name="TopTick" Visibility="Collapsed" Fill="LightGray" Placement="Top" SnapsToDevicePixels="True"
                 Height="4" Margin="0,0,0,2" />
        <ProgressBar x:Name="TrackProgressBar" Grid.Row="1" HorizontalAlignment="Stretch" Height="10" VerticalAlignment="Center" 
                 Margin="8,0,8,0" Foreground="CadetBlue"></ProgressBar>
        <Track x:Name="PART_Track" Grid.Row="1">
            <Track.DecreaseRepeatButton>
                <RepeatButton Command="{x:Static Slider.DecreaseLarge}"  Style="{StaticResource SliderRepeatButtonStyle}" />
            </Track.DecreaseRepeatButton>
            <Track.IncreaseRepeatButton>
                <RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource SliderRepeatButtonStyle}"/>
            </Track.IncreaseRepeatButton>
            <Track.Thumb>
                <Thumb x:Name="Thumb" Style="{StaticResource SliderThumbStyle}" />
            </Track.Thumb>
        </Track>
        <TickBar x:Name="BottomTick" Grid.Row="2" Visibility="Collapsed" Fill="LightGray" Placement="Bottom"
             SnapsToDevicePixels="True" Height="4" Margin="0,2,0,0"/>
    </Grid>
<ControlTemplate>

Шаг 2: Создайте вложенные свойства, которые можно туннелировать вниз, чтобы найти ProgressBar:

public class SliderProgressBarAttachedProperty : DependencyObject
{
    public static readonly DependencyProperty ProgressValueProperty =
        DependencyProperty.RegisterAttached("ProgressValue", typeof(int), typeof(SliderProgressBarAttachedProperty), new PropertyMetadata(OnItemsChanged));

    public static int GetProgressValue(DependencyObject obj)
    {
        return (int)obj.GetValue(ProgressValueProperty);
    }
    public static void SetProgressValue(DependencyObject obj, int value)
    {
        obj.SetValue(ProgressValueProperty, value);
    }

    public static readonly DependencyProperty ProgressMaximumProperty =
        DependencyProperty.RegisterAttached("ProgressMaximum", typeof(int), typeof(SliderProgressBarAttachedProperty), new PropertyMetadata(OnItemsChanged));

    public static int GetProgressMaximum(DependencyObject obj)
    {
        return (int)obj.GetValue(ProgressMaximumProperty);
    }

    public static void SetProgressMaximum(DependencyObject obj, int value)
    {
        obj.SetValue(ProgressMaximumProperty, value);
    }

    private static void OnItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var slider = d as Slider;

        var progressValue = GetProgressValue(d);
        var progressMaximum = GetProgressMaximum(d);

        if (slider == null) return;

        var progressBar = slider.Template.FindName("TrackProgressBar",slider) as ProgressBar;

        if (progressBar == null) return;

        progressBar.Maximum = progressMaximum;
        progressBar.Value = progressValue;
    }
}

Шаг 3: Предотвратите перемещение ползунка за пределы значения ProgressBar, реализовав обработчик для ValueChanged:

    private void RangeBase_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        var slider = sender as Slider;


        if (slider == null) return;


        var progressBar = (ProgressBar)slider.Template.FindName("TrackProgressBar", slider);


        if (progressBar == null) return;


        if (e.NewValue > progressBar.Value)
        {
            slider.Value = progressBar.Value;
            e.Handled = true;
            return;
        }
    }
...