2011-06-14 122 views
2

我在調整Listview控件大小時遇到​​了一點問題。我打算根據窗口的實際大小按比例調整大小。如何按比例調整WPF Listview?

對於Listview的初始大小,它的像素爲300 X 600(寬X高)。而且我還設置了maxHeight至750,但它的寬度保持不變,即300

此外,在Wondow的屬性,我已經改變了SizeToContent屬性WidthAndHeight,因爲一些線程建議通過這樣做可以讓系統在調整窗口大小後決定控件的大小。

但是,它還沒有工作。所以我在這裏尋求幫助。謝謝。

P.S.無論如何,我們可以在WPF中設置寬度和高度的百分比值嗎?如果我被允許使用百分比,那麼會更容易,比如height = 80%。

編輯:

使其更清晰,這裏是XAML

<Grid Height="Auto"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="50" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
     </Grid.ColumnDefinitions> 
    <StackPanel Grid.Row="0" Orientation="Horizontal" Height="Auto" Margin="0"> 
     <ListView /> 
    </StackPanel> 
    <StackPanel Grid.Row="1" Orientation="Horizontal" Height="Auto" Margin="0"> 
     <Label /> 
     <Button /> 
    </StackPanel> 
</Grid> 

正如你所看到的,我目前使用2塊堆棧板,並把它們在不同的行一般的代碼結構。但即使我改變,Listview仍然無法按比例調整大小。

回答

3

將您的ListView網格內,並使用「*」寬度特徵爲柱:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="4*" /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 

    <ListView Grid.Column="0">...</ListView> 
</Grid> 

列0在本實施例中具有「4 *」與列的寬度1具有默認寬度爲「1 *」。這意味着它們之間的寬度是「五顆星」,第0列是四個寬度。這給你一個80%的寬度。

+0

什麼ListView控件的寬度和高度?我應該爲兩個屬性定義一個固定值,還是隻說「自動」? – woodykiddy 2011-06-14 04:21:10

+0

是的,只是放棄width屬性並讓它填充列。同樣,如果您在網格中定義行並希望其垂直自動調整大小,那麼也適用於高度。 – 2011-06-14 04:23:20

+0

如果我用ListPanel包裝Listview,還需要改變什麼?似乎StackPanel不接受'*'。 – woodykiddy 2011-06-14 04:33:13

2

只是一個供參考的東西,我發現,工作

Here is a Value Converter that can be used with a ListView and allow star column sizing

從文章:

/// <summary> 
/// Calculates the column width required to fill the view in a GridView 
/// For usage examples, see http://leghumped.com/blog/2009/03/11/wpf-gridview-column-width-calculator/ 
/// </summary> 
public class WidthConverter : IValueConverter { 
/// <summary> 
/// Converts the specified value. 
/// </summary> 
/// <param name="value">The parent Listview.</param> 
/// <param name="type">The type.</param> 
/// <param name="parameter"> 
/// If no parameter is given, the remaning with will be returned. 
/// If the parameter is an integer acts as MinimumWidth, the remaining with will be returned only if it's greater than the parameter 
/// If the parameter is anything else, it's taken to be a percentage. Eg: 0.3* = 30%, 0.15* = 15% 
/// </param> 
/// <param name="culture">The culture.</param> 
/// <returns>The width, as calculated by the parameter given</returns> 
public object Convert(object value, Type type, object parameter, CultureInfo culture) { 
    if(value == null) return null; 
    ListView listView = value as ListView; 
    GridView grdView = listView.View as GridView; 
    int minWidth = 0; 
    bool widthIsPercentage = parameter != null && !int.TryParse(parameter.ToString(), out minWidth); 
    if(widthIsPercentage) { 
     string widthParam = parameter.ToString(); 
     double percentage = double.Parse(widthParam.Substring(0, widthParam.Length - 1)); 
     return listView.ActualWidth * percentage; 
    } else { 
     double total = 0; 
     for(int i = 0; i < grdView.Columns.Count - 1; i++) { 
      total += grdView.Columns[i].ActualWidth; 
     } 
     double remainingWidth = listView.ActualWidth - total; 
     if(remainingWidth > minWidth) { // fill the remaining width in the ListView 
      return remainingWidth; 
     } else { // fill remaining space with MinWidth 
      return minWidth; 
     } 
    }    
} 

public object ConvertBack(object o, Type type, object parameter, CultureInfo culture) { 
    throw new NotSupportedException(); 
} 
} 

如果你不帶任何參數調用它,它會佔用剩餘寬度在ListView中:

// fills remaining width in the ListView 
<GridViewColumn Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListView}},Converter={StaticResource WidthConverter}}"> 

如果您使用整數作爲參數,該值將作爲最小寬度

// fills remaining width in the ListView, unless the remaining width is less than the parameter 
<GridViewColumn Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListView}},Converter={StaticResource WidthConverter},ConverterParameter=200}"> 

或者,你可以指定有星號的GridView控件類型寬度和ListView控件的百分比寬度將返回

// calculates 30% of the ListView width 
<GridViewColumn Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListView}},Converter={StaticResource WidthConverter},ConverterParameter=0.3*}"> 
+0

對於我來說,在列已被賦予寬度之前,這會被調用。因此'grdView.Columns [i] .ActualWidth'總是爲零。 – canton7 2016-09-01 10:51:46

+0

這是不完整的例子。 如何在xaml中聲明WidthConverter? – luka 2017-11-17 08:21:06

0

這是我用來按比例調整WPF ListView的列的大小,以便在調整大小後不會顯示水平滾動條。這可以處理任意數量的列以及存在垂直滾動條。沒有使用轉換器,只有大小改變的事件處理程序。到目前爲止,這是行之有效的。唯一的缺點是當用戶調整窗口大小時,水平滾動條有時會​​閃爍。

LV_FileList.SizeChanged += this.onLV_FileList_SizeChanged; 

...

/// <summary> 
    /// Proportionally resize listview columns when listview size changes 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void onLV_FileList_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     if ((sender is ListView) && 
      (e.PreviousSize.Width > 0)) 
     { 
      double total_width = 0; 
      GridViewColumnCollection gvcc = ((GridView)(sender as ListView).View).Columns; 
      foreach (GridViewColumn gvc in gvcc) 
      { 
       gvc.Width = (gvc.Width/e.PreviousSize.Width) * e.NewSize.Width; 
       total_width += gvc.Width; 
      } 

      //Increase width of last column to fit width of listview if integer division made the total width to small 
      if (total_width < e.NewSize.Width) 
      { 
       gvcc[gvcc.Count - 1].Width += (e.NewSize.Width - total_width); 
      } 

      //Render changes to ListView before checking for horizontal scrollbar 
      this.AllowUIToUpdate(); 

      //Decrease width of last column to eliminate scrollbar if it is displayed now 
      ScrollViewer svFileList = this.FindVisualChild<ScrollViewer>(LV_FileList); 
      while ((svFileList.ComputedHorizontalScrollBarVisibility != Visibility.Collapsed) && (gvcc[gvcc.Count - 1].Width > 1)) 
      { 
       gvcc[gvcc.Count - 1].Width--; 
       this.AllowUIToUpdate(); 
      } 
     } 
    } 


    /// <summary> 
    /// Threaded invocation to handle updating UI in resize loop 
    /// </summary> 
    private void AllowUIToUpdate() 
    { 
     DispatcherFrame dFrame = new DispatcherFrame(); 

     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter) 
     { 
      dFrame.Continue = false; 
      return null; 

     }), null); 

     Dispatcher.PushFrame(dFrame); 
    }