2010-01-22 37 views
16

我有一個簡單的WrapPanel其中包含一些廣泛的控制。當我調整WindowWidth時,一切正常。如果有足夠的空間,則控件將在單行上傳遞,或者在沒有足夠空間時包裝到下一行。WPF包裝面板和滾動

但是,我需要發生的是,如果所有的控件基本上是垂直堆疊的(因爲沒有更多的水平空間)並且WindowWidth降低得更多,所以會出現一個水平滾動條,可以滾動並查看整個控件,如果我想。以下是我的xaml。我試圖用WrapPanel包裝ScrollViewer,但我無法實現我的目標。

<Window x:Class="WpfQuotes.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="Auto" Width="600" Foreground="White"> 
    <WrapPanel> 
     <Button Width="250">1</Button> 
     <Button Width="250">2</Button> 
     <Button Width="250">3</Button> 
    </WrapPanel> 
</Window> 

所以,如果你減少以上Window到最小的Width,你將無法看到按鈕的文本。我想要一個水平滾動條出現,這樣我就可以滾動查看文本,但不會干擾通常的包裝功能。

謝謝。

更新: 我跟着保羅的建議下面和水平滾動條出現如預期現在。不過,我也想垂直滾動,所以我設置了VerticalScrollBarVisibility="Auto"。問題是,如果我調整窗口大小以使垂直滾動條出現,即使不需要水平滾動條(水平空間足以查看整個控件),也會始終顯示水平滾動條。看起來似乎垂直滾動條出現了與scrollviewer的寬度混亂。有沒有辦法糾正這個問題,除非實際需要水平滾動條?

下面是我的XAML和我在CustomWrapPanel添加的唯一代碼:

<Window x:Class="Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:cwp="clr-namespace:CustomWrapPanelExample" 
     Title="Window1" Height="Auto" Width="300" Foreground="White" Name="mainPanel"> 
    <ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto" 
       VerticalScrollBarVisibility="Auto"> 
    <cwp:CustomWrapPanel Width="{Binding ElementName=MyScrollViewer, Path=ActualWidth}"> 
     <Button Width="250">1</Button> 
     <Button Width="250">2</Button> 
     <Button Width="250">3</Button> 
     <Button Width="250">4</Button> 
     <Button Width="250">5</Button> 
     <Button Width="250">6</Button> 
     <Button Width="250">7</Button> 
     <Button Width="250">8</Button> 
     <Button Width="250">9</Button> 
    </cwp:CustomWrapPanel> 
    </ScrollViewer> 
</Window> 

CustomWrapPanel覆蓋的唯一的事:

protected override Size MeasureOverride(Size availableSize) 
{ 
    double maxChildWidth = 0; 
    if (Children.Count > 0) 
    { 
    foreach (UIElement el in Children) 
    { 
     if (el.DesiredSize.Width > maxChildWidth) 
     { 
     maxChildWidth = el.DesiredSize.Width; 
     } 
    } 
    }  
    MinWidth = maxChildWidth; 
    return base.MeasureOverride(availableSize); 
} 
+0

你可以用ScrollViewer發佈XAML嗎? – hackerhasid 2010-01-22 17:26:36

回答

43

事情是這樣的,如果你要使用一個包它會做兩件事,它將佔用一個方向上的可用空間,並在另一方面根據需要擴展。例如,如果將它放置在窗口內部,就像它擁有它一樣,它佔用儘可能多的水平空間,然後根據需要向下擴展,這就是垂直滾動條工作的原因,父容器說「這是我有多寬,但是你可以讓自己像垂直想要的那樣大「,如果你把它改成水平滾動條,那麼滾動查看器本質上是說」這可能會有多高,但你可以像你想要「在這種情況下,包裝面板不會換行,因爲沒有水平約束。

一個潛在的解決辦法是改變畫布面板從水平換到垂直這樣的方向(這可能不是理想的或預期的行爲):

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> 
     <WrapPanel Orientation="Vertical"> 
      <Button Width="250">1</Button> 
      <Button Width="250">2</Button> 
      <Button Width="250">3</Button> 
     </WrapPanel> 
    </ScrollViewer> 

爲了讓您的期望的行爲,你必須做一些接近這個:

<ScrollViewer x:Name="MyScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> 
     <WrapPanel MinWidth="250" Width="{Binding ElementName=MyScrollViewer, Path=ViewportWidth}"> 
      <Button Width="250">1</Button> 
      <Button Width="250">2</Button> 
      <Button Width="250">3</Button> 
     </WrapPanel> 
    </ScrollViewer> 

但是,如果你已經知道你的孩子元素的寬度第二種解決方案僅適用,最好你希望你的最大寬度設置爲實際寬度最大的兒童項目,但在o爲了做到這一點,你必須創建一個自定義控件,它可以從wrap面板派生出來並自己編寫代碼來檢查它。

+0

謝謝保羅。我按照你所描述的做了改變,現在它運行得更好。但是,我看到一個小問題w.r.t.垂直滾動。我還想要一個垂直滾動條出現,只要包裝面板的項目不完全可見垂直。我編輯了我原來的帖子,以顯示我所做的更改以及我面臨的問題。 – Flack 2010-01-22 19:14:00

+0

Ahh ...玩了一下,你所需要做的就是將包裝面板上的綁定路徑從ActualWidth更改爲ViewportWidth,當垂直滾動條被添加時,它使得視口寬度更小,儘管實際控制保持相同的尺寸。這應該解決你看到的奇怪的水平滾動條錯誤,我會更新我的帖子。 – 2010-01-22 21:39:42

+0

優秀!它現在看起來很完美。非常感謝您的幫助:) – Flack 2010-01-22 21:52:52