#c# #wpf #datagrid #column-width
#c# #wpf #datagrid #ширина столбца
Вопрос:
У меня есть эта DataGrid, которая выглядит следующим образом, когда я загружаю данные в первый раз:
итак, это почти идеально, но то, что я действительно хочу, отображается при максимальном изменении размера окна — столбцы теперь расположены следующим образом:
Я хотел бы расположить самые правые столбцы в правой части представления DataGrid, а в левом столбце выделить остальную часть представления.
Мой вопрос: могу ли я вызвать событие в DataGrid, чтобы вызвать такое расположение столбцов, которое в противном случае происходило бы только при максимальном увеличении окна?
Упрощенная версия XAML DataGrid выглядит следующим образом:
<DataGrid
ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
AutoGenerateColumns="False"
GridLinesVisibility="None"
ColumnWidth="*">
<DataGrid.Columns>
<DataGridTemplateColumn Width="*" Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Text="{Binding ItemName}"
ToolTipService.ShowOnDisabled="true"
>
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="Auto" Header="Size">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ItemLengthA}"
HorizontalAlignment="Right"
Margin="3,0,0,0"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="Auto" Header="Modified">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ItemLastUpdateA}"
HorizontalAlignment="Right"
Margin="3,0,0,0"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
У меня также есть рабочее приложение / элемент управления для проверки здесь, но я думаю, что просмотра приведенного выше XAML должно быть достаточно, чтобы найти решение, основанное на заданном макете.
Комментарии:
1. Мне кажется, что с кодом все в порядке. Я тестировал аналогичное
DataGrid
с некоторыми данными, оно просто продолжает отображаться как ваше второе изображение, независимо от того, как был изменен размер. Так что, возможно, на макет повлияла какая-то другая вещь.2. Вы размещаете свою сетку данных внутри окна с SizeToContent =»WidthAndHeight» или SizeToContent = «Width»? Я столкнулся с подобным поведением, когда окно адаптируется к ширине содержимого.
3. Код окна — это просто стандартный код, который вы получите, если создадите новый проект WPF — никаких особых вещей там нет. Есть некоторые другие функции, такие как синхронизация прокрутки и настройка цвета фона в стиле строк, которые я могу попытаться отключить, чтобы посмотреть, изменится ли поведение, но до сих пор я не думал, что это будет иметь значение… Я проверю, изменяет ли отключение поведение ширины столбца…
Ответ №1:
Я попытался воспроизвести ваш случай и пришел к результату: это зависит от того, как вы будете использовать ItemsSource. В случае, если ItemsSource в ViewModel представляет собой список, тогда вы можете просто назначить ему новый экземпляр и вызвать событие PropertyChanged. Это приведет к тому, что столбцы будут вести себя так, как вы хотите (Width=»Auto»).
ItemsSource = new List<Data>();
// ItemsSource.Add(new Data()); // ..adding data
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ItemsSource)));
Однако, поскольку в настоящее время это не работает, я предполагаю, что у вас, возможно, есть ObservableCollection в качестве ItemsSource, и вы добавляете элементы туда. В моих тестах он ведет себя так, как вы описали, столбцы остаются маленькими, если не изменять размер окна или столбцов вручную.
public ObservableCollection<Data> ItemsSource { get; set; }
public void AddItems()
{
ItemsSource.Add(new Data()); // not working
}
Единственный способ, который я нашел, чтобы заставить сетку сделать это, заключался в том, чтобы изменить ширину столбца с Auto на некоторое значение, а затем обратно. Для этого используется кнопка. но любая загрузка также будет работать
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (DataGridTemplateColumn item in MyDataGrid.Columns)
{
if (item.Width.IsAuto)
{
item.Width = new DataGridLength(item.ActualWidth, item.Width.UnitType);
item.Width = DataGridLength.Auto;
}
}
}
Комментарии:
1. Я могу проверить ваши выводы — я также могу воспроизвести то же самое требуемое поведение с ObservableCollection<> — похоже, дело не в типе коллекции, а в том факте, что существующая коллекция действительно заменяется новой коллекцией, за которой следует событие PropertyChanged, которое заставляет это работать. ObservableCollection фактически отправляет NotifyCollectionChangedAction. Сброс, но это, по-видимому, недостаточно разумно для того, чтобы Сетка действительно правильно распределяла элементы. Итак, решение теперь состоит в том, чтобы всегда восстанавливать всю (наблюдаемую) коллекцию при каждой перезагрузке … спасибо за подсказку 🙂