2012-06-22 6 views
3

У меня есть сетка данных:Как получить общую высоту содержимого DataGrid в WPF?

<DataGrid x:Name="Foo" ... /> 

я хотел бы связать высоту такого элемента на высоту сетки данных. Просто делать {Binding ElementName=Foo, Path=ActualHeight} не будет работать, потому что он принимает высоту ScrollViewer, а не общую высоту содержимого сетки данных.

ответ

2

Вы должны найти DataGrid ВНУТРЕННЕГО ScrollViewer, и связываются с его ViewportHeight

В зависимости от того, что вы делаете с этим значением, и где вам это нужно, это может быть сделано различными способами.

Обычно такого рода вещи нужно для View-Only цели, так что я бы поставил код, чтобы найти высоту ViewPort в CodeBehind

Например, с помощью некоторых VisualTreeHelpers, вы могли бы сделать что-то вроде этого:

// Find first child of type ScrollViewer in object Foo 
var scrollViewer = VisualTreeHelpers.FindChild<ScrollViewer>(Foo); 

// If object is found, set other control's height to ViewportHeight 
if (scrollViewer != null) 
{ 
    MyControl.Height = scrollViewer.ViewportHeight; 
} 

Я не могу вспомнить, если есть больше чем один ScrollViewer в DataGrid ... вы должны были бы использовать что-то вроде Snoop, чтобы узнать наверняка. Если есть, есть перегрузка .FindChild(), чтобы найти элемент по имени, который вы должны использовать. Название может быть получено через что-то вроде Snoop.

Это также может быть сделано в Converter, где вы передаете DataGrid к конвертеру, и есть его найти ScrollViewer и ViewportHeight в конвертер

<Grid Height="{Binding ElementName=Foo, 
         Converter={StaticResource GetDataGridContentHeight}}" /> 

Редактировать

я действительно сделал несколько тестов, а DataGrid's ScrollViewer обрабатывает размеры немного по-другому, возможно, из-за Virtualization. По-видимому, они используют относительные размеры в зависимости от количества строк.

Тест DataGrid Я работал с 23 рядами. ScrollViewer.ExtentHeight был равен 23, а ScrollViewer.ViewportHeight - 3, что означает, что было всего 23 строки, и были показаны 3 полные строки. ScrollViewer.ScrollableHeight был равен 20, то есть я мог прокручивать от 0 до 20 (поскольку показано 3 элемента, ему не нужно идти до 23), а ScrollViewer.VerticalOffset был установлен на любой элемент, к которому в данный момент прокручивался.

Таким образом, чтобы получить фактическую высоту содержимого элементов в виртуальной ScrollViewer, я думаю, что вы будете иметь, чтобы получить ActualHeight одного из видимых строк, и умножить его на ScrollViewer.ExtentHeight, чтобы получить фактический размер вашего содержание. Это будет работать, только если Height всех ваших товаров одинаково.

+0

Помощник визуального дерева не может найти средство просмотра прокрутки? Я использовал хелпер-код как есть и пробовал его, как и выше. Является ли 'Foo' экземпляром' DataGrid'? – Tower

+0

@rFactor Да, 'Foo' - это имя' DataGrid'. Я сделал быстрый тест, и он возвращает 'ScrollViewer' просто найти с помощью этого кода. Вы случайно используете 'VisualTreeHelper' вместо' VisualTreeHelpers'? (обратите внимание на 's' в конце ... Я назвал это, прежде чем замечать что-то уже существовавшее, которое было названо очень похожим). – Rachel

+0

Метод говорит:« Ищет дочерний элемент управления в родительском типе ». Поэтому я думаю, что это правильно. Однако, что вы подразумеваете под словом «Foo - это имя DataGrid»? Имя? Вы имеете в виду, что 'Foo' является экземпляром' DataGrid'? – Tower

0

Вы можете обернуть DataGrid в другом ScrollViewer, а затем фактическую высоту DataGrid.

Однако это связано с невыполнением штрафных санкций за невозможность использования виртуализации строк DataGrid. Вам придется протестировать и посмотреть, оказывает ли это существенное негативное влияние на ваш случай использования или нет.

+0

Извините, но это невозможно в моем сценарии. – Tower

+0

@rFactor из-за виртуализации, о которой я упоминал? –

+0

Да, у меня много рядов. – Tower

Смежные вопросы