He hecho algo similar y la mejor manera que encontré para hacer esto fue poner su contenido en un visor de desplazamiento y simplemente desactivar las barras de desplazamiento. Luego, codifique sus botones para desplazar el scrollviewer.
Editar: Respondiendo a comentario sobre no hay manera de lidiar con el tamaño.
En primer lugar, construirías este control como ContentControl. Debería tener una plantilla definida en generic.xaml que tenga los controles de tu botón más el visor de desplazamiento. Algo así como:
<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>
Luego, en el control de lo que se necesita para anular 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;
}
En su botón de clic manipuladores que tendría que (1) desplazarse el espectador y (2) comprobar la nueva valor de HorizontalOffset para ver si necesita ocultar o mostrar cualquiera de los botones.
Descargo de responsabilidad: Probablemente este código no funcione como está, ya que fue escrito a mano y basado en un ejemplo diferente.
El problema con este método es que no veo un evento que podría adjuntar a, que me notificará cuando la ventana gráfica haya cambiado de tal manera que los botones deben hacerse visibles. Entonces, en efecto, tendré que hacer que los botones estén siempre visibles, lo que no me gusta. – Nick