WPF DataGrid не уменьшается при уменьшении ширины столбца - PullRequest
5 голосов
/ 15 ноября 2010

Я использую DataGrid в WPF и хочу сжать его, чтобы он соответствовал ширине его столбцов. Это делает это красиво для начального рендеринга. Когда я изменяю размер столбца, чтобы сделать его шире, растёт и сетка. Но если изменить размер столбца, чтобы он снова стал уже, я получаю пустое пространство с правой стороны столбца (и вижу, что серая область заголовка столбца выходит за пределы столбцов.

Я бы хотел, чтобы сетка данных сужала свою ширину столбцами, чтобы я не получил пустое пространство справа. Я попытался отладить код, и, насколько я вижу, проблема в DataGridCellsPanel, но я не вижу места, где можно исправить измерение ширины.

Любая помощь будет оценена.

Ответы [ 3 ]

3 голосов
/ 16 ноября 2010

У меня была эта проблема некоторое время назад, и я был настолько раздражен этим, что я сделал уродливое решение для нее.Это не красиво, но это делает работу.Во-первых, это проблема, только когда горизонтальная полоса прокрутки невидима, поэтому нам понадобится ссылка на нее.Этот код необходимо будет выполнить после загрузки всех DataGridColumns (в моем случае все в Xaml, поэтому событие Loaded), и он не учитывает добавление / удаление DataGridColumns, но это легко исправить.

<DataGrid Name="c_dataGrid"
          Loaded="c_dataGrid_Loaded"
          ...>
    <DataGrid.Columns>
        <DataGridTextColumn ..."/>
        <DataGridTextColumn ..."/>
        <!-- ... -->

Затем в Loaded EventHandler мы получаем DataGrid ScrollViewer и добавляем прослушиватель для изменений в ActualWidthProperty каждого DataGridColumn в DataGrid.

private ScrollViewer m_dataGridScrollViewer = null;
private void c_dataGrid_Loaded(object sender, RoutedEventArgs e)
{
    m_dataGridScrollViewer = GetVisualChild<ScrollViewer>(c_dataGrid);
    DependencyPropertyDescriptor dependencyPropertyDescriptor =
        DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
    if (dependencyPropertyDescriptor != null)
    {
        foreach (DataGridColumn column in c_dataGrid.Columns)
        {
            dependencyPropertyDescriptor.AddValueChanged(column, DataGridColumn_ActualWidthChanged);
        }
    }
}

И затем мы вычисляем размер DataGrid изразмер всех DataGridColumns и добавьте константу 8.0 (что обычно является разницей).

private void DataGridColumn_ActualWidthChanged(object sender, EventArgs e)
{
    if (m_dataGridScrollViewer != null)
    {
        if (m_dataGridScrollViewer.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
        {
            double dataGridWidth = 8.0;
            foreach (DataGridColumn column in c_dataGrid.Columns)
            {
                dataGridWidth += column.ActualWidth;
            }
            c_dataGrid.Width = dataGridWidth;
        }
        else
        {
            c_dataGrid.Width = double.NaN;
        }
    }
}

Если вы найдете лучший способ сделать это, то дайте мне знать:)

public static T GetVisualChild<T>(object parent) where T : Visual
{
    DependencyObject dependencyObject = parent as DependencyObject;
    return InternalGetVisualChild<T>(dependencyObject);
}
private static T InternalGetVisualChild<T>(DependencyObject parent) where T : Visual
{
    T child = default(T);

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
            break;
        }
    }
    return child;
}
2 голосов
/ 16 ноября 2010

Это хорошее решение.Я немного подправил его, чтобы вместо него было установлено свойство MaxWidth.Это решает проблему расширения сетки за пределы ограничений визуального родителя.Вместо этого я также преобразовал его в поведение, чтобы лучше его инкапсулировать.

Это то, с чем я закончил.две сетки, но, похоже, работает на одну.

0 голосов
/ 09 мая 2011

Кажется, есть небольшая проблема с обоими вашими подходами. Когда я перетаскиваю крайний левый столбец вправо, вся сетка изменяется или катится изнутри (к сожалению, у меня недостаточно репутации для публикации изображения).

Итак, я изменил функцию jjrdk ResizeGrid, чтобы она вычисляла ширину последнего столбца и расширяла ее до конца влево. Сетка HorizontalAlignment и HorizontalContentAlignment должны быть установлены в HorizontalAlignment.Stretch.

void ResizeGrid(object sender, EventArgs e) 
    {
         var scroll = ExTreeHelper.FindVisualChild<ScrollViewer>(AssociatedObject);

        if (scroll != null && null != AssociatedObject.Columns && AssociatedObject.Columns.Count > 0)
        {
            var lastColumn = AssociatedObject.Columns.Last();

            double dataGridWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth) + 2.0;

            if (scroll.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
            {
                RemoveListener(lastColumn);

                AssociatedObject.Columns.Last().Width =
                    AssociatedObject.Columns.Last().Width.DisplayValue + scroll.ViewportWidth - dataGridWidth;

                AssociatedObject.Width = dataGridWidth + scroll.ViewportWidth - dataGridWidth;

                AddListener(lastColumn);
            }
            else
            {
                AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
                AssociatedObject.HorizontalContentAlignment = HorizontalAlignment.Stretch;

                AssociatedObject.Width = double.NaN;
            }
        }         }  

Единственная проблема, с которой я столкнулся, это то, что полоса прокрутки всегда есть, даже если все столбцы были вписаны.

Есть еще одна проблема, когда все столбцы свернуты влево, он начинает мигать.

Есть ли что-нибудь, что можно сделать, чтобы действительно избавиться от этого белого пространства?

Leon

...