Обновление: Я превратил этот ответ в статью проекта кода здесь: http://www.codeproject.com/KB/WPF/ScatterViewSizing.aspx - проверьте это для более подробной информации и полного примера кода
Это очень сложно понять правильно. У меня была эта проблема некоторое время назад, и я попробовал много разных подходов - я даже реализовал свой собственный ScatterViewItem для обработки автоматического определения размера - но так и не нашел 100% работающего решения.
Решение, которое я решил, которое решило мою основную проблему получения правильного начального размера , состояло в том, чтобы создать пользовательский элемент управления, который использовал вложенные свойства для установки размера его родительского ScatterViewItem при создании. Полный код для этого достаточно большой, чтобы разместить его здесь, но я постараюсь объяснить суть его, чтобы вы начали.
Таким образом, всякий раз, когда я добавлял материал в мое представление рассеяния (посредством привязки данных), мой шаблон элемента устанавливал содержимое элемента ScatterViewItem для моего элемента управления, называемого «PopupWindow» (который происходит от UserControl). PopupWindow определило вложенное свойство с именем InitialSizeRequest
(типа Size ), которое оно будет искать в своем дочернем элементе. В своем обработчике Loaded
он будет искать визуальное дерево вверх, чтобы найти ScatterViewItem, а затем соответственно устанавливать его размер.
Сгенерированное визуальное дерево будет выглядеть так:
ScatterView
'- ScatterViewItem
'- PopupWindow
'- ActualContent (datatemplate)
На фактическом контенте они объявили бы свой размер следующим образом:
<UserControl x:Class="...."
...
localview:PopupWindow.InitialSizeRequest="450,400" />
Чтобы получить актуальный контент из PopupWindow, я использовал приведенный ниже код (проверка ошибок опущена). Это выполняется в событии Loaded
PopupWindow:
// GuiHelpers is a helper class I built to find elements in the visual tree
// c_contentHolder is a ContentControl which will hold the actual content
var presenter = GuiHelpers.GetChildObject<ContentPresenter>(c_contentHolder);
// It seems it's safe to assume the ContentPresenter will always only have one
// child and that child is the visual representation of the actual content.
var child = VisualTreeHelper.GetChild(presenter, 0);
Size requestedSize = PopupWindow.GetInitialSizeRequest(child);
// Now use requestedSize to set the size of the parent ScatterViewItem
var svi = GuiHelpers.GetParentObject<ScatterViewItem>(this, false);
svi.Width = requestedSize.Width;
svi.Height = requestedSize.Height;
Надеюсь, это поможет вам начать. Пожалуйста, прокомментируйте, если вам нужны дальнейшие объяснения.