ScatterViewItem нестандартный размер
Я разрабатываю поверхностное приложение, используя шаблон MVVM. У меня есть разные виды, и я хочу разместить их в одном ScatterView. Я хочу, чтобы размер ScatterViewItem соответствовал размеру моих просмотров?
пример кода:
<DataTemplate DataType="{x:Type vm:PointListViewModel}">
<Grid>
<v:PointListView>
</v:PointListView>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:BluetoothDevicesViewModel}">
<Grid>
<v:BluetoothDevicesView></v:BluetoothDevicesView>
</Grid>
</DataTemplate>
....
<s:ScatterView Grid.RowSpan="3"
DataContext="{Binding Path=Workspaces}"
ItemsSource="{Binding}"
ItemTemplate="{Binding}"
ClipToBounds="True" AllowDrop="True">
</s:ScatterView>
... Этот код работает нормально, но все мои представления имеют одинаковый размер. Я попытался настроить ScatterViewItem со стилем, как:
<Style BasedOn="{StaticResource {x:Type s:ScatterViewItem}}"
TargetType="{x:Type s:ScatterViewItem}">
<Setter Property="Height" Value="Auto" />
<Setter Property="Width" Value="Auto" />
</Style>
Но это не работает.
1 ответ
Обновление: я превратил этот ответ в статью проекта кода здесь: 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;
Надеюсь, это поможет вам начать. Пожалуйста, прокомментируйте, если вам нужны дальнейшие объяснения.