簡體   English   中英

ScrollViewer是否可見?

[英]ScrollViewer is visible?

我正在使用ComputedHorizo​​ntalScrollBarVisibility,但是當您將Horizo​​ntalScrollBarVisibility設置為“ 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 ,並將其與比較ActualWidthScrollViewer 如果總和小於ScrollViewerActualWidth ,則需要滾動。

有關更多詳細信息,請參閱此鏈接

以我的經驗,滾動查看器屬性值可能會過時,直到下一個布局通過為止。 在下面的簡單示例中,它位於代碼的后面,但這確實可以按照您想要的方式工作。

我創建了一個名為“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM