2012-11-15 28 views
0

考慮以下XAML:約束網格行與身高=自動可視區域

<Window x:Class="WpfApplication4.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" MinHeight="100" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <ListBox> 
     <ListBox.Items> 
     <ListBoxItem>a</ListBoxItem> 
     <!-- Another 11 items --> 
     </ListBox.Items> 
    </ListBox> 
    <ListBox Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible"> 
     <ListBox.Items> 
     <ListBoxItem>1</ListBoxItem> 
     <!-- Another 23 items --> 
     </ListBox.Items> 
    </ListBox> 
    </Grid> 
</Window> 

第二行中的列表框中顯示了垂直滾動條的禁止,只是切斷內容。

我希望它被限制在窗口的可見區域。如何實現這一目標?

理性背後的第二個網格行的高度設置爲自動: 我想第二個列表框,以顯示其所有內容,而無需滾動條如果有足夠的空間供其和第一ListBox中應該採取的剩餘空間。

+0

第一個'listBox'應該佔用剩餘空間,第二個應占用可用空間。但是需要限制其他人進行評估。不是嗎? –

+0

有一個約束,首先ListBox有一個MinHeight設置爲100. – Sisyphe

回答

1

我不認爲有任何方法可以在純XAML中執行所需操作 - 您必須爲兩個列表框中的一個或另一個設置特定高度,或爲它們設置固定比例。

我想你可以用後面的代碼中的一些代碼來做你想做的事情。給你的RowDefinitions和列表框的名稱,具體如下,並訂閱GridSizedChanged事件:

<Grid SizeChanged="GridSizeChanged"> 
    <Grid.RowDefinitions> 
     <RowDefinition x:Name="row1"/> 
     <RowDefinition x:Name="row2"/> 
    </Grid.RowDefinitions> 
    <ListBox x:Name="lb1"> 
     <ListBox.Items> 
      <ListBoxItem>a</ListBoxItem> 
     </ListBox.Items> 
    </ListBox> 
    <ListBox x:Name="lb2" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible"> 
     <ListBox.Items> 
      <ListBoxItem>1</ListBoxItem> 
      <!-- Another 23 items --> 
     </ListBox.Items> 
    </ListBox> 
</Grid> 

然後作如下處理方式的事件:

private void GridSizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    double newHeight = e.NewSize.Height; 
    int lb1ItemCount = lb1.Items.Count; 
    int lb2ItemCount = lb2.Items.Count; 
    row1.Height = new GridLength(newHeight * lb1ItemCount/(lb1ItemCount + lb2ItemCount)); 
    row2.Height = new GridLength(newHeight * lb2ItemCount/(lb1ItemCount + lb2ItemCount)); 
} 

這將2個列表框的大小爲與他們內部物品的數量成正比。如果要爲第一個列表框設置最小大小爲100,則必須先做更多工作來設置該大小,然後將第二個大小從第一個大小的計算值中去除。

編輯: 我想我已經寫了一個版本的GridSizeChanged,完全符合你的要求。這個版本會將lb2的高度設置爲整個網格,除了頂部100px(如果所需的列表框大小大於此值),或者只是其自身所需的大小(如果較小)。然後,第一個列表框將填充所有剩餘空間,並且根據需要將具有100px的最小高度,因爲我們不允許lb2填充頂部100px。

private void GridSizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    lb2.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
    double lb2DesiredHeight = lb2.DesiredSize.Height; 

    double newHeight = e.NewSize.Height; 
    double lb2AvailableHeight = newHeight - 100; 

    double lb2ActualHeight = Math.Min(lb2DesiredHeight, lb2AvailableHeight); 
    row1.Height = new GridLength(newHeight - lb2ActualHeight); 
    row2.Height = new GridLength(lb2ActualHeight); 
} 
+0

感謝您的努力。但是,它不起作用,因爲網格的大小不是窗口的大小,而是其內容的大小。此外,我想要一個更通用的版本。目前,你已經硬編碼了上面的列表框的100個。 –

+0

可能你最好的選擇就是重寫Grid類。然後,您可以使上述GridSizeChanged函數的通用版本完成您想要的功能,並且還可以使任何可變參數(例如100大小)成爲該新Grid控件的依賴項屬性。 –