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

发布于 2024-09-12 23:51:11 字数 525 浏览 7 评论 0原文

让一组 DataGrid 列具有比例宽度 (Width="\*") 的最佳/正确方法是什么,但要使其最小< /strong> 宽度至少是其内容的宽度?目前,如果我使用 Width="*",那么列将保持完全成比例,但如果列变得太细,内容就会被裁剪。如果我使用 Width="Auto",那么列的大小完全适合其内容,但这使它们的大小不同。

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

遗憾的是, MinWidth="Auto" 不存在,所以我想我需要绑定列的 MinWidth 属性,但很难确切地弄清楚我要绑定它的内容到。

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

What would be the best/right way to have a set of DataGrid columns have proportional width (Width="\*"), but to have their minimum width be at least the width of their content? At the moment, if I use Width="*", then the columns stay exactly proportional, but content gets cropped if the columns get too thin. If I use Width="Auto", then the columns size themselves perfectly to their content, but this makes them all different sizes.

What I want is really a combination of the two, like Width="\*", MinWidth="Auto" so that when there's extra width the columns will all space out to equal widths, but when the grid is made smaller, the content never gets cropped.

Sadly, MinWidth="Auto" doesn't exist, so I guess I need to bind the column's MinWidth property, but it's hard to figure out exactly what I would bind it to.

How do I tell WPF "MinWidth=" the width of the column's widest piece of content?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

难如初 2024-09-19 23:51:12

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

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

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

如果您有多个 MinWidth 值的候选值,则需要自己编写一个 IMultiValueConverter,它接受一个 object[],将其解析为浮点数,并返回最大值 (如果您只自己使用它并且不需要处理转换器的不良使用,那么它只是 1 个 linq 查询)

这种方式还支持 MinWidth 的动态更改。

I know its a bit late, but I found your question and programmed a pure-XAML solution.

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

Where the ElementName points to the control taking up most of the space. Of course thats only possible to do with elements, that do have a limited width.
If you do it for example for a GroupBox, than you can resize only to larger width and never resize to smaller one.

If you have several candidates for the value of MinWidth, you need to write yourself a IMultiValueConverter, which takes an object[], parses it to floats, and returns the maximum (its just 1 linq query if you use it only yourselves and don't need to handle bad usage of the converter)

This way also supports dynamic changing of the MinWidth.

如若梦似彩虹 2024-09-19 23:51:12

在 XAML 中设置 Width = "Auto"

然后在代码中:

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

Set Width = "Auto" in XAML.

Then in the code:

MinWidth = ActualWidth
Width = new GridLength(1, GridUnitType.Star)
—━☆沉默づ 2024-09-19 23:51:12

我在 GridViewColumn 内正确调整网格列大小时也遇到问题。我尝试了很多东西,但后来我发现了 UniformGrid。这对我来说是最终的解决方案。它就是有效的。我以前不知道它......默认情况下它似乎不存在于 VS 工具箱中(?),因此甚至不知道它存在。

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

I also had problems to size Grid columns correctly inside the GridViewColumn. There were several things that I tried but then I found the UniformGrid. It was the ultimate solution for me. It just works. I haven't knew it before...seems that it doesn't exist in VS toolbox by default (?) and thus didn't know it even exists.

You can find more about UniformGrid from here.

维持三分热 2024-09-19 23:51:12

您可以为 Grid 控件创建一个依赖属性(例如称为 Horizo​​ntalPropFillOfBlankSpace),这将确保您需要的内容(宽度为“*”的列,但 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);
         }
      }
   }
}

You can create a dependency property (called e.g. HorizontalPropFillOfBlankSpace) for Grid control which will ensure what you need (columns with Width="*", but MinWidth to fit contents). Then you can apply it on any grid you want:

<Grid namespace:GridHelper.HorizontalPropFillOfBlankSpace="True">
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="Auto" />
   </Grid.ColumnDefinitions>
   ...

You can see an example of the implementation of this dependency property below. Only columns with Width="Auto" are automatically resized to fill gap space. It can be customized by you what you need.

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);
         }
      }
   }
}
豆芽 2024-09-19 23:51:12

在 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
}

Give the column a name in the XAML:

<Grid>
      <Grid.ColumnDefinitions>
             <ColumnDefinition Width="*" Name="Col1"/>
             <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
</Grid>

Then set the MinWidth property in the code as shown below:

public MainWindow()
{
    InitializeComponent();

    Col1.MinWidth = 340; //enter desired minimum width here
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文