Silverlight Scrollviewer только с кнопками

Я использую ScrollViewer как часть моего приложения Silverlight. Он имеет горизонтальную ориентацию, и я бы хотел, чтобы он выглядел так, чтобы отображались только кнопки прокрутки, но не сама полоса прокрутки. Что-то вроде этого грубого рендеринга ASCII:

------------------------------------------------------
|   |                                            |   |
| < |                Content Here                | > |
|   |                                            |   |
------------------------------------------------------

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


person Nick    schedule 17.12.2008    source источник


Ответы (4)


Вот еще вариант. Переопределите шаблон по умолчанию для SCrollviewer и обработайте кнопки как PageUp / PageDown. Мой пример ниже - это средство просмотра с вертикальной прокруткой. Вы можете легко перейти на горизонтальную прокрутку и изменить обработчики с PageUp / PageDown на левые и правые обработчики.

<ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer">
        <ControlTemplate.Resources>
            <!-- Add style here for repeat button seen below -->
        </ControlTemplate.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <RepeatButton Grid.Row="0"
                          Foreground="White" 
                          Background="Yellow" 
                          HorizontalAlignment="Stretch" 
                          Command="ScrollBar.PageUpCommand"
                          Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}">
            </RepeatButton>

            <ScrollContentPresenter
                CanContentScroll="{TemplateBinding CanContentScroll}"
                Grid.Row="1" 
                Content="{TemplateBinding Content}"  
                Width="{TemplateBinding Width}"
                Height="{TemplateBinding Height}" 
                Margin="{TemplateBinding Margin}"/>

            <RepeatButton Grid.Row="2" Background="Black" Foreground="White" Command="ScrollBar.PageDownCommand">
            </RepeatButton>
        </Grid>
    </ControlTemplate>
person Louis    schedule 17.12.2008
comment
StackOverflow хромает. Мои правки не отображаются. Очевидно, что в приведенном выше примере отсутствует некоторая информация в верхней части шаблона элемента управления, но в режиме редактирования все это есть. Можно просто переопределить шаблон ScrollViewer, чтобы получить эффект только кнопки. - person Louis; 18.12.2008
comment
Кажется, это решение WPF. Как это сделать в Silverlight? Command = ScrollBar.PageUpCommand не работает в Silverlight. - person Tim Cochran; 02.09.2011

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

Изменить: ответ на комментарий об отсутствии возможности изменить размер.

Во-первых, вы должны создать этот элемент управления как ContentControl. Он должен иметь шаблон, определенный в generic.xaml, в котором есть элементы управления кнопками и средство просмотра прокрутки. Что-то типа:

<Canvas x:Name="root">
  <Button x:Name="left" Content="<"/>
  <Button x:Name="right" Content=">"/>
  <ScrollViewer x:Name="viewer" BorderThickness="0" VerticalScrollBarVisibility="Hidden">
    <ContentPresenter />
  </ScrollViewer>
</Canvas>

Затем в вашем элементе управления вам нужно будет переопределить OnApplyTemplate:

public override void OnApplyTemplate()
{
  base.OnApplyTemplate();

  left = GetTemplateChild("left") as Button;
  left.Click += new RoutedEvent(YourHandler);
  right = GetTemplateChild("right") as Button;
  right.Click += new RoutedEvent(YourHandler);
  // position your scroll buttons here, not writing that code
  scroll = GetTemplateChild("viewer") as ScrollViewer;
  root = GetTemplateChild("root") as Canvas;

  var fe = this.Content as FrameworkElement;
  if (fe != null)
  {
    fe.SizeChanged += new SizeChangedEventHandler(fe_SizeChanged);
  }
}

void  fe_SizeChanged(object sender, SizeChangedEventArgs e)
{
  this.InvalidateMeasure();
}

protected override Size ArrangeOverride(Size finalSize)
{
  if (!double.IsInfinity(scroll.ViewportHeight))
  {
     left.Visibility = (scroll.HorizontalOffset > 0);
     right.Visibility = (scroll.HorizontalOffset < ScrollableHeight);
  }
  return base.ArrangeOverride(finalSize);
}

protected override Size MeasureOverride(Size availableSize)
{
  scroll.Measure(availableSize);
  return scroll.DesiredSize;
}

В обработчиках нажатия кнопок вам нужно будет (1) прокрутить средство просмотра и (2) проверить новое значение HorizontalOffset, чтобы увидеть, нужно ли вам скрыть или показать любую из кнопок.

Отказ от ответственности: этот код, вероятно, не работает как есть, поскольку он был написан вручную и основан на другом примере.

person Bryant    schedule 17.12.2008
comment
Проблема с этим методом заключается в том, что я не вижу события, к которому я мог бы присоединиться, которое уведомляло бы меня, когда область просмотра изменилась таким образом, что кнопки должны быть сделаны видимыми. По сути, мне пришлось бы сделать кнопки всегда видимыми, что мне не нравится. - person Nick; 17.12.2008

я нашел решение здесь :)

http://weblogs.asp.net/fredriknormen/archive/2009/09/18/create-an-automatic-scrollable-image-slider-in-silverlight.aspx

Это сделано с использованием DispatcherTimer, действительно хороший пример :)

person Fernando    schedule 20.08.2010

Уже довольно много времени ищу рабочее решение. И на основе решения Луи мне удалось заставить его работать. (в WPF)

Это решение для горизонтальной прокрутки.

Во-первых, добавьте ListView:

    <ListView ItemsSource="{Binding Items}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.Template>
            <ControlTemplate>
                <ScrollViewer Template="{StaticResource ButtonOnlyScrollViewer}">
                    <ItemsPresenter />
                </ScrollViewer>
            </ControlTemplate>
        </ListView.Template>
    </ListView>

И модифицированный шаблон из ответа Луи для горизонтальной прокрутки:

    <ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <RepeatButton Content="&lt;"
                          Grid.Column="0"
                          Command="ScrollBar.LineLeftCommand"
                          Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>

            <ScrollContentPresenter
                CanContentScroll="{TemplateBinding CanContentScroll}"
                Grid.Column="1" 
                Content="{TemplateBinding Content}"  
                Width="{TemplateBinding Width}"
                Height="{TemplateBinding Height}" 
                Margin="{TemplateBinding Margin}"/>

            <RepeatButton Content="&gt;"
                          Grid.Column="2" 
                          Command="ScrollBar.LineRightCommand"
                          Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
        </Grid>
    </ControlTemplate>
person Ladislav Ondris    schedule 14.08.2017