2011-06-14 81 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); 
    }