2014-07-24 218 views
0

我正在使用ComputedHorizo​​ntalScrollBarVisibility,但當您將Horizo​​ntalScrollBarVisibility設置爲「隱藏」時,這不起作用。ScrollViewer可見?

我想要實現的是知道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

你設置'Horizo​​ntalScrollBarVisibility'到'Auto',我認爲它,就等於'Visibility.Collapsed'(不'Hidden')和在佈局上不會佔用任何空間。 – Sinatr

+0

是的,這是所需的效果,但是當它可見時,我想顯示按鈕而不是滾動查看器 – user3873453

+0

您可能需要創建自己的ScrollViewer控件,該控件仍需要進行測量,但不顯示ScrollViewer, –

回答

0

您可以通過簡單地將ScrollViewer內的內容元素的寬度相加來獲得所需內容,例如,如果在ScrollViewer內有StackPanel(含Orientation=Horizontal),則將StackPanel中每個子元素的寬度相加,並將其與的ActualWidth進行比較。如果總和小於ActualWidthScrollViewer那麼你需要滾動它。

欲瞭解更多詳情,請參閱本link

0

如果你需要控制的ScrollViewer的方式(或任何控制,真的)被擺出來,可以考慮使用ControlTemplate,這在任何控制的Template財產入店。因爲這將允許您將對象本身和值傳遞給它,並提供這樣的模板。但是,這可能涉及需要處理計算以顯示可見的控件的確切部分。

0

在我的經驗中,滾動瀏覽器屬性值可以是過時的,直到下一個佈局傳遞。在我下面的簡單示例中,它是代碼隱藏的,但這種方式按照您的方式工作。

我創建了一個名爲「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> 

更新:

怎麼樣新方法適用於多個滾動查看器和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 > 

這在我的測試的偉大工程。這是一個有趣的挑戰。也許有人可以用更好的方法啓發我們,但我對此很滿意。

+0

我的問題是所有這些代碼是在ItemsControl的內部,所以我有幾個ScrollViewers和StackPanels的按鈕,你的方法我怎麼知道哪個滾動是? – user3873453

+0

我最終做了非常相似的事情,但沒有約束能見度。謝謝! – user3873453

0

謝謝大家的答案,但終於得到了解決辦法更容易一點,而不是結合從按鈕的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; 
     } 
    } 
} 
相關問題