Я использую ScrollViewer как часть моего приложения Silverlight. Он имеет горизонтальную ориентацию, и я бы хотел, чтобы он выглядел так, чтобы отображались только кнопки прокрутки, но не сама полоса прокрутки. Что-то вроде этого грубого рендеринга ASCII:
------------------------------------------------------
| | | |
| < | Content Here | > |
| | | |
------------------------------------------------------
Я знаю, что могу использовать функции шаблонов, но все образцы, которые я видел, изменяют только внешний вид всех элементов, а не их исходное расположение или даже то, появляются ли они вообще. Возможно ли это сделать, и может ли кто-нибудь дать общее представление о том, как может выглядеть шаблон?





Я сделал нечто подобное, и лучший способ, который я нашел для этого, - это поместить ваш контент в средство просмотра прокрутки и просто отключить полосы прокрутки. Затем закодируйте свои кнопки для прокрутки средства просмотра прокрутки.
Редактировать: Ответ на комментарий о том, что нет возможности заниматься калибровкой.
Во-первых, вы должны создать этот элемент управления как 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, чтобы увидеть, нужно ли вам скрыть или показать любую из кнопок.
Отказ от ответственности: этот код, вероятно, не работает как есть, поскольку он был написан вручную и основан на другом примере.
Вот еще вариант. Переопределите шаблон по умолчанию для 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>
StackOverflow хромает. Мои правки не отображаются. Очевидно, что в приведенном выше примере отсутствует некоторая информация в верхней части шаблона управления, но в режиме редактирования все это есть. Можно просто переопределить шаблон ScrollViewer, чтобы получить эффект только кнопки.
Кажется, это решение WPF. Как это сделать в Silverlight? Command = "ScrollBar.PageUpCommand" не работает в Silverlight.
я нашел решение здесь :)
Это сделано с использованием DispatcherTimer, действительно хороший пример :)
Уже довольно много времени ищу рабочее решение. И на основе решения Луи мне удалось заставить его работать. (в 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 = "<"
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 = ">"
Grid.Column = "2"
Command = "ScrollBar.LineRightCommand"
Visibility = "{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
Проблема с этим методом заключается в том, что я не вижу события, к которому я мог бы присоединиться, которое уведомляло бы меня, когда область просмотра изменилась таким образом, что кнопки должны быть сделаны видимыми. По сути, мне пришлось бы сделать кнопки всегда видимыми, что мне не нравится.