[英]ScrollViewer is visible?
我正在使用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 >
如果需要控制ScrollViewer(或實際上是任何控件)的布局方式,請考慮使用ControlTemplate
,該ControlTemplate
可在任何Control的Template
屬性中使用。 因為這將允許您綁定到對象本身和傳入的值,並提供此類模板。 但是,這可能涉及需要處理計算以顯示控件的確切部分(可見)。
你可以得到你想要通過簡單的相加里面的內容元素的寬度什么ScrollViewer
,例如,如果你有一個StackPanel
(與Orientation=Horizontal
內) ScrollViewer
然后加起來每個子元素的寬度在StackPanel
,並將其與比較ActualWidth
的ScrollViewer
。 如果總和小於ScrollViewer
的ActualWidth
,則需要滾動。
有關更多詳細信息,請參閱此鏈接
以我的經驗,滾動查看器屬性值可能會過時,直到下一個布局通過為止。 在下面的簡單示例中,它位於代碼的后面,但這確實可以按照您想要的方式工作。
我創建了一個名為“ ShowScrollButtons”的依賴項屬性。 您可能可以觀察范圍和視口大小的變化,並自動重新計算該屬性。
當滾動內容大小更改時,我觸發了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>
更新:
一種新方法如何與多個滾動查看器和StackPanels一起使用而無需代碼隱藏。
使用附加屬性來控制外部按鈕的可見性:
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 >
這在我的測試中效果很好。 這是一個有趣的挑戰。 也許有人可以用更好的方法啟發我們,但對此我感到非常滿意。
謝謝大家的回答,但最終得到了一些解決方法,而不是從按鈕的StackPanel
綁定可見性,只需在ScrollViewer
調用ScrollChanged
,然后在代碼中檢查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;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.