我使用ComputedHorizontalScrollBarVisibility但是当您将HorizontalScrollBarVisibility设置为" Hidden"时,这不起作用。
我想要实现的目标是知道ScrollViewer
是否应该可见而不显示ScrollViewer
。然后绑定该结果以显示控制ScrollViewer
的按钮(在本例中为下面的“StackPanel”)。
XAML
<ScrollViewer HorizontalScrollBarVisibility="Auto" x:Name="Scroll">
.....
</ScrollViewer>
<StackPanel Visibility="{Binding ElementName=Scroll, Path=ComputedHorizontalScrollBarVisibility}">
<Button Grid.Column="0" Content="Left" HorizontalAlignment="Left" Click="..."/>
<Button Grid.Column="1" Content="Right" HorizontalAlignment="Right" Click="..."/>
</StackPanel >
答案 0 :(得分:0)
如果您需要控制ScrollViewer(或任何控件,实际上)的布局方式,请考虑使用ControlTemplate
,这可以在任何Control的Template
属性中访问。因为这将允许您绑定到对象本身和传递给它的值,并提供这样的模板。但是,这可能涉及需要处理计算以显示可见的控件的确切部分。
答案 1 :(得分:0)
您可以通过简单地在ScrollViewer
内添加内容元素的宽度来获得您想要的内容,例如如果StackPanel
内有Orientation=Horizontal
(ScrollViewer
},请在StackPanel
中加上每个子元素的宽度,并将其与ActualWidth
的{{1}}进行比较{1}}。如果总和小于ScrollViewer
的{{1}},则需要滚动它。
有关详细信息,请参阅此link
答案 2 :(得分:0)
根据我的经验,滚动查看器属性值可能是陈旧的,直到下一个布局传递。它在我下面的简单示例中代码隐藏,但这确实可以按照您想要的方式运行。
我创建一个名为&#34; ShowScrollButtons&#34;的依赖项属性。您可以观察范围和视口大小更改并自动重新计算属性。
当滚动内容大小发生变化时,我会触发重新评估ShowScrollButtons。请注意对UpdateLayout的调用,以确保范围和视口大小是最新的。同样,它是一个示例,所以我只在这里检查左/右滚动按钮的宽度
private void UpdateScrollButtonVis()
{
UpdateLayout();
ShowScrollButtons = (Scroll.ExtentHeight > Scroll.ViewportWidth);
}
在XAML ......
<Window.Resources>
<BooleanToVisibilityConverter x:Key="boolvis"/>
</Window.Resources>
<Grid x:Name="theGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Width="100" Height="100" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden" x:Name="Scroll">
<Canvas x:Name="theCanvas" Width="300" Height="300" Background="Green"/>
</ScrollViewer>
<StackPanel Grid.Row="1" Visibility="{Binding ShowScrollButtons,Converter={StaticResource boolvis}}">
<Button Grid.Column="0" Content="Left" HorizontalAlignment="Left" />
<Button Grid.Column="1" Content="Right" HorizontalAlignment="Right" />
</StackPanel >
<Button x:Name="toggle" Grid.Row="2" Height="25" Width="100" Click="toggle_Click">Toggle</Button>
</Grid>
<强>更新强>
新方法如何与多个滚动查看器和StackPanel一起使用,而无需代码隐藏。
使用附加属性来控制外部按钮可见性:
public class ScrollViewWatcher
{
public static readonly DependencyProperty HorizontalButtonVisibility = DependencyProperty.RegisterAttached(
"HorizontalButtonVisibility",
typeof(Visibility),
typeof(ScrollViewWatcher),
new FrameworkPropertyMetadata(Visibility.Visible,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure)
);
public static Visibility GetHorizontalButtonVisiblity(UIElement element)
{
return (Visibility)element.GetValue(HorizontalButtonVisibility);
}
public static void SetHorizontalButtonVisibility(UIElement element, Visibility value)
{
element.SetValue(HorizontalButtonVisibility, value);
ScrollViewer sv = element as ScrollViewer;
if (sv != null)
{
sv.ScrollChanged -= sv_ScrollChanged;
sv.ScrollChanged += sv_ScrollChanged;
}
}
static void sv_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
var sv = sender as ScrollViewer;
if (sv != null)
{
var vis = sv.ExtentHeight > sv.ViewportWidth ? Visibility.Visible : Visibility.Hidden;
sv.SetValue(HorizontalButtonVisibility, vis);
}
}
}
然后在XAML中,绑定到相应的ScrollViewer,如下所示:
<ScrollViewer
x:Name="sv1" local:ScrollViewWatcher.HorizontalButtonVisibility="Visible"
Grid.Row="0" Width="100" Height="100" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden" >
<Canvas x:Name="theCanvas" Width="300" Height="300" Background="Green"/>
</ScrollViewer>
<StackPanel Grid.Row="1" Visibility="{Binding ElementName=sv1,Path=(local:ScrollViewWatcher.HorizontalButtonVisibility), Mode=OneWay}">
<Button Grid.Column="0" Content="Left" HorizontalAlignment="Left" />
<Button Grid.Column="1" Content="Right" HorizontalAlignment="Right" />
</StackPanel >
这在我的测试中效果很好。这是一个有趣的挑战。也许有人可以用更好的方法来启发我们,但我对此非常满意。
答案 3 :(得分:0)
谢谢大家的答案,但最终得到的解决方法更容易,而不是绑定按钮的StackPanel
的可见性,只需在ScrollChanged
中调用ScrollViewer
,然后在代码中检查ComputedHorizontalScrollBarVisibility
并根据结果改变可见性。
XAML
<ScrollViewer HorizontalScrollBarVisibility="Auto" x:Name="Scroll" ScrollChanged="Scroll_ScrollChanged">
.....
</ScrollViewer>
<StackPanel x:Name="BPanel" Visibility="Hidden">
<Button Grid.Column="0" Content="Left" HorizontalAlignment="Left" Click="..."/>
<Button Grid.Column="1" Content="Right" HorizontalAlignment="Right" Click="..."/>
</StackPanel >
C#
private void Scroll_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
ScrollViewer scroll = (ScrollViewer)sender;
if(scroll.HorizontalScrollBarVisibility == ScrollBarVisibility.Auto)
{
if (scroll.ComputedHorizontalScrollBarVisibility == Visibility.Visible)
{
scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
BPanel.Visibility = Visibility.Visible;
}
}
}