WPF - DataGrid列宽度为"*",但最小宽度适合内容

37
什么是使一组DataGrid列具有比例宽度(Width="*"),但这些列的最小宽度至少要等于其内容宽度的最佳/正确方法?目前,如果我使用Width="*",则列会保持完全成比例,但如果列变得太窄,则内容将被裁剪。如果我使用Width="Auto",则列的大小完美地调整为其内容,但这会使它们的大小不同。
实际上我希望两者的结合,就像Width="*",MinWidth="Auto"一样,以便当有额外的宽度时,所有列将间隔相等,但当网格变小时,内容永远不会被裁剪。
不幸的是,MinWidth="Auto"不存在,所以我想必须绑定列的MinWidth属性,但很难确定我要绑定到什么。如何告诉WPF将MinWidth设置为列最宽的内容宽度?

3
允许我们设置MinWidth="auto"将是一个不错的功能。 - Patrick Szalapski
5个回答

22

我知道可能有点晚了,但我找到了你的问题并编写了一个纯XAML解决方案。

 <ColumnDefinition Width="42*" MinWidth="{Binding Path=ActualWidth, ElementName=projectInfoHeader }"/> 

如果ElementName指向控件的占用大部分空间,那么可以进行自适应调整大小。当然,只有具有有限宽度的元素才能这样做。

如果你对MinWidth的值有多个候选项,你需要编写一个IMultiValueConverter,它接受一个对象数组,将其解析为浮点数,并返回最大值(如果只用于自己并且不需要处理转换器的错误使用,则只是一个Linq查询)

这种方法也支持动态更改MinWidth


13

在XAML中设置Width = "Auto"

然后在代码中:

MinWidth = ActualWidth
Width = new GridLength(1, GridUnitType.Star)

1
对我有用。循环遍历网格中的所有列,并在其中执行上述代码。将循环放入网格“Loaded”事件的处理程序中。 - saus
即使有这个帮助,我也花了一段时间才弄明白。请查看我在https://dev59.com/fmYr5IYBdhLWcg3wfaSc的回答。 - Brent

1
我在GridViewColumn里正确设置Grid列的大小也遇到了问题。我尝试了几种方法,但最终找到了UniformGrid。对我来说,这是最终的解决方案。它就是有效的。我以前不知道它的存在...似乎它不是默认存在于VS工具箱中(?),因此甚至不知道它的存在。
您可以从这里了解更多关于UniformGrid的信息。

0
你可以为Grid控件创建一个依赖属性(例如称为HorizontalPropFillOfBlankSpace),以确保你所需的效果(列宽度为“*”,但最小宽度适合内容)。然后,你可以将其应用于任何想要的网格:
<Grid namespace:GridHelper.HorizontalPropFillOfBlankSpace="True">
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="Auto" />
   </Grid.ColumnDefinitions>
   ...

您可以在下面看到此依赖属性实现的示例。仅具有 Width =“Auto” 的列会自动调整大小以填充间隙空间。您可以根据需要进行自定义。
public class GridHelper
{
   /// <summary>
   /// Columns are resized to proportionally fill horizontal blank space.
   /// It is applied only on columns with the Width property set to "Auto".
   /// Minimum width of columns is defined by their content.
   /// </summary>
   public static readonly DependencyProperty HorizontalPropFillOfBlankSpaceProperty =
      DependencyProperty.RegisterAttached("HorizontalPropFillOfBlankSpace", typeof(bool), typeof(GridHelper), new UIPropertyMetadata(false, OnHorizontalPropFillChanged));

   public static bool GetHorizontalPropFillOfBlankSpace(Grid grid)
      => (bool)grid.GetValue(HorizontalPropFillOfBlankSpaceProperty);

   public static void SetHorizontalPropFillOfBlankSpace(Grid grid, bool value)
      => grid.SetValue(HorizontalPropFillOfBlankSpaceProperty, value);

   private static void OnHorizontalPropFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
      if (!(d is Grid grid))
         return;

      if ((bool)e.NewValue)
      {
         grid.Loaded += Grid_Loaded;
      }
      else
      {
         grid.Loaded -= Grid_Loaded;
      }
   }

   private static void Grid_Loaded(object sender, RoutedEventArgs e)
   {
      if (!(sender is Grid grid))
         return;

      foreach (var cd in grid.ColumnDefinitions)
      {
         if (cd.Width.IsAuto && cd.ActualWidth != 0d)
         {
            if (cd.MinWidth == 0d)
               cd.MinWidth = cd.ActualWidth;
            cd.Width = new GridLength(1d, GridUnitType.Star);
         }
      }
   }
}

-1
在XAML中为该列命名:
<Grid>
      <Grid.ColumnDefinitions>
             <ColumnDefinition Width="*" Name="Col1"/>
             <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
</Grid>

然后在代码中设置MinWidth属性,如下所示:

public MainWindow()
{
    InitializeComponent();

    Col1.MinWidth = 340; //enter desired minimum width here
}

4
你可以将Minwidth和Maxwidth添加为列属性,无需修改后台代码。 - Rukshan Dangalla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接