WPF - столбец DataGrid с шириной = *, но минимальной шириной для размещения содержимого

Каким будет наилучший / правильный способ, чтобы набор DataGrid столбцов имел пропорциональную ширину (Width="\*"),, но чтобы их минимальная ширина была не меньше ширины их содержимого? На данный момент, если я использую Width="*" , то столбцы остаются точно пропорциональными, но содержимое обрезается, если столбцы становятся слишком тонкими.Если я использую Width="Auto", тогда размеры самих столбцов идеально соответствуют их содержимому, но это делает их все разных размеров.

На самом деле мне нужна комбинация этих двух элементов, например Width="\*", MinWidth="Auto", чтобы при дополнительной ширине все столбцы занимали одинаковую ширину, но когда сетка становится меньше, содержимое никогда не обрезается.

К сожалению, MinWidth="Auto" не существует, поэтому я предполагаю, что мне нужно привязать свойство столбца MinWidth, но трудно понять, к чему я бы его привязал.

Как сообщить WPF "MinWidth=" ширину самого широкого фрагмента содержимого столбца?


person Andy T    schedule 04.08.2010    source источник
comment
Было бы неплохо дать нам возможность установить MinWidth = auto.   -  person Patrick Szalapski    schedule 26.05.2011


Ответы (5)


Я знаю, что это немного поздно, но я нашел ваш вопрос и запрограммировал решение на чистом XAML.

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

Где ElementName указывает на элемент управления, занимающий большую часть места. Конечно, это возможно только с элементами, которые имеют ограниченную ширину. Если вы сделаете это, например, для GroupBox, тогда вы сможете изменить размер только до большей ширины и никогда не уменьшать размер до меньшей.

Если у вас есть несколько кандидатов на значение MinWidth, вам нужно написать себе IMultiValueConverter, который принимает объект [], анализирует его на float и возвращает максимум (это всего 1 запрос linq, если вы используете его только сами и не не нужно справляться с неправильным использованием конвертера)

Этот способ также поддерживает динамическое изменение MinWidth.

person Tomas Grosup    schedule 03.07.2012

Установите Width = "Auto" в XAML.

Затем в коде:

MinWidth = ActualWidth
Width = new GridLength(1, GridUnitType.Star)
person Anon    schedule 25.10.2010
comment
Работал у меня. Прокрутите все столбцы в сетке и выполните приведенный выше код во всех из них. поместите цикл в обработчик события Loaded сетки - person saus; 18.02.2011
comment
Мне потребовалось некоторое время, чтобы разобраться даже с этой помощью. См. Мой ответ на странице stackoverflow.com / questions / 13631694 / - person Brent; 29.11.2012

У меня также были проблемы с правильным размером столбцов сетки внутри GridViewColumn. Я попробовал несколько вещей, но потом нашел UniformGrid. Для меня это было идеальным решением. Просто работает. Я не знал этого раньше ... кажется, что он не существует в панели инструментов VS по умолчанию (?) И, следовательно, не знал, что он даже существует.

Дополнительную информацию о UniformGrid можно найти здесь.

person Ollikat    schedule 26.02.2014

Вы можете создать свойство зависимости (например, HorizontalPropFillOfBlankSpace) для элемента управления Grid, которое обеспечит то, что вам нужно (столбцы с Width = *, но 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);
         }
      }
   }
}
person Marek S.    schedule 02.10.2020

Дайте столбцу имя в 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
}
person danielcooperxyz    schedule 20.09.2012
comment
вы можете добавить Minwidth и Maxwidth как атрибуты столбца. Не нужно добавлять прикосновение к коду позади - person Rukshan Dangalla; 20.07.2017