WPF - Столбец DataGrid с шириной ="*", но минимальной шириной, чтобы соответствовать содержимому
Что было бы лучшим / правильным способом иметь набор DataGrid
столбцы имеют пропорциональную ширину (Width="\*"),
но чтобы их минимальная ширина была как минимум шириной их содержимого? На данный момент, если я использую Width="*"
, тогда столбцы остаются точно пропорциональными, но содержимое обрезается, если столбцы становятся слишком тонкими. Если я использую Width="Auto"
тогда столбцы сами по размеру соответствуют своему содержанию, но это делает их всех разных размеров.
То, что я хочу, это действительно сочетание двух, как Width="\*"
, MinWidth="Auto"
так что, когда есть дополнительная ширина, все столбцы будут разнесены до одинаковой ширины, но когда сетка станет меньше, содержимое никогда не будет обрезано.
К сожалению, MinWidth="Auto"
не существует, поэтому я думаю, мне нужно связать столбец MinWidth
собственности, но трудно точно понять, к чему я бы это привязал.
Как мне сказать WPF "MinWidth="
ширина самого широкого столбца контента?
4 ответа
Я знаю, что уже поздно, но я нашел ваш вопрос и запрограммировал решение на чистом XAML.
<ColumnDefinition Width="42*" MinWidth="{Binding Path=ActualWidth, ElementName=projectInfoHeader }"/>
Где ElementName
указывает на контроль, занимающий большую часть пространства. Конечно, это возможно только с элементами, которые имеют ограниченную ширину. Если вы делаете это, например, для GroupBox
, чем вы можете изменить размер только на большую ширину и никогда не изменять размер на меньшую.
Если у вас есть несколько кандидатов на значение MinWidth
, вам нужно написать себе IMultiValueConverter
, который берет объект [], анализирует его до числа с плавающей запятой и возвращает максимум (это всего лишь 1 запрос linq, если вы используете его только сами и не должны обрабатывать неправильное использование конвертера)
Этот способ также поддерживает динамическое изменение MinWidth
,
Задавать Width = "Auto"
в XAML.
Тогда в коде:
MinWidth = ActualWidth
Width = new GridLength(1, GridUnitType.Star)
У меня также были проблемы с правильным размером столбцов Grid внутри GridViewColumn. Я попробовал несколько вещей, но потом нашел UniformGrid. Это было окончательное решение для меня. Это просто работает. Я не знал этого раньше... кажется, что он не существует в VS toolbox по умолчанию (?) И, следовательно, не знал, что он даже существует.
Вы можете найти больше о UniformGrid здесь.
Дайте столбцу имя в 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
}
Вы можете создать свойство зависимости (называемое, например,
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);
}
}
}
}