开发者

ScatterViewItem custom size

I develop surface app using MVVM pattern. I have different Views and I want to place them into one ScatterView. I want my ScatterViewItem size correspond t开发者_Python百科o the size of my Views?

code example:

        <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>

... This code works fine but all my Views have the same size. I tried to configure ScatterViewItem with style like:

       <Style BasedOn="{StaticResource {x:Type s:ScatterViewItem}}"      
              TargetType="{x:Type s:ScatterViewItem}">

        <Setter Property="Height" Value="Auto" />
        <Setter Property="Width" Value="Auto" />
       </Style>

But it doesn't work.


Update: I've turned this answer into a code project article here: http://www.codeproject.com/KB/WPF/ScatterViewSizing.aspx - check that out for more details and full sample code


This is very tricky to get right. I had this problem a while ago and tried many different approaches - I even implemented my own ScatterViewItem to handle automatic sizing - but never found a 100% working solution.

The solution I did settle for, that solved my main problem of getting the initial size correct was to create a custom control that used attached properties to set the size of its parent ScatterViewItem when it's created. The full code for this is way to large to place here, but I'll try to explain the core of it to get you started.

So whenever I added stuff into my scatterview (through databinding), my itemtemplate would set the content of the ScatterViewItem to my control called "PopupWindow" (which derived from UserControl). The PopupWindow defined an attached property called InitialSizeRequest (of type Size) that it would look for in its child element. In its Loaded event handler it would search the visual tree upwards to locate the ScatterViewItem and then set its size accordingly.

The generated visual tree would look like this:

ScatterView
  '- ScatterViewItem
      '- PopupWindow
          '- ActualContent (datatemplate)

On the actual content, they would declare their size like so:

<UserControl x:Class="...."
 ...
  localview:PopupWindow.InitialSizeRequest="450,400" />

To get hold of the actual content from the PopupWindow, I used the code below (error checking omitted). This is executed in the Loaded event of the 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;

Hopefully this should get you started. Please comment if you need further explainations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜