WPF - 宽度为“*”的 DataGrid 列,但 MinWidth 以适合内容

Posted

技术标签:

【中文标题】WPF - 宽度为“*”的 DataGrid 列,但 MinWidth 以适合内容【英文标题】:WPF - DataGrid Column with Width="*", but MinWidth to Fit Contents 【发布时间】:2011-03-25 03:52:30 【问题描述】:

让一组DataGrid 列具有成比例的宽度(Width="\*"), 但使其最小宽度至少是其内容的宽度?在此刻,如果我使用Width="*",那么列保持完全成比例,但如果列太薄,内容会被裁剪。如果我使用Width="Auto",那么列的大小会完全适合它们的内容,但这会使它们全部不同的尺寸。

我真正想要的是两者的结合,比如Width="\*"MinWidth="Auto",这样当有额外的宽度时,列将全部间隔到相等的宽度,但是当网格变小时,内容永远不会得到裁剪。

遗憾的是,MinWidth="Auto" 不存在,所以我想我需要绑定列的 MinWidth 属性,但很难弄清楚我会将它绑定到什么。

如何告诉 WPF "MinWidth=" 列的最宽内容的宽度?

【问题讨论】:

让我们能够设置 MinWidth="auto" 将是一个不错的功能。 【参考方案1】:

我知道这有点晚了,但我发现了你的问题并编写了一个纯 XAML 解决方案。

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

ElementName 指向占据大部分空间的控件。当然,这仅适用于宽度有限的元素。 例如,如果您为 GroupBox 执行此操作,则只能将其调整为较大的宽度,而不能调整为较小的宽度。

如果您有多个MinWidth 值的候选者,您需要为自己编写一个IMultiValueConverter,它接受一个对象[],将其解析为浮点数,并返回最大值(如果您只供自己使用,不需要处理转换器的不良使用)

这种方式还支持MinWidth的动态变化。

【讨论】:

【参考方案2】:

在 XAML 中设置 Width = "Auto"

然后在代码中:

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

【讨论】:

为我工作。遍历网格中的所有列并在所有列中执行上面的代码。将循环放在网格的 Loaded 事件的处理程序中 即使有这个帮助,我也花了一段时间才弄清楚。在***.com/questions/13631694/…查看我的回答【参考方案3】:

在 GridViewColumn 内正确调整 Grid 列的大小时,我也遇到了问题。我尝试了几件事,但后来我找到了 UniformGrid。这对我来说是最终的解决方案。它只是工作。我以前不知道它...似乎默认情况下它在VS工具箱中不存在(?),因此甚至不知道它存在。

您可以从here 找到有关 UniformGrid 的更多信息。

【讨论】:

【参考方案4】:

您可以为 Grid 控件创建一个依赖属性(例如 HorizontalPropFillOfBlankSpace),这将确保您需要什么(宽度为“*”的列,但 MinWidth 以适应内容)。然后你可以将它应用到任何你想要的网格上:

<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);
         
      
   

【讨论】:

【参考方案5】:

在 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

【讨论】:

您可以添加 Minwidth 和 Maxwidth 作为列属性。后面不用加touch代码

以上是关于WPF - 宽度为“*”的 DataGrid 列,但 MinWidth 以适合内容的主要内容,如果未能解决你的问题,请参考以下文章

XAML WPF DataGrid:在滚动时减小列宽度以适应其内容,除了一个

wpf datagrid 的单元格内容超出列宽度

wpf datagrid自适应列宽错位

找不到将Wpf DataGrid列绑定到属性的方法[关闭]

WPF DataGrid 同步列宽

WPF DataGrid:滚动时减小列宽以适合其内容