ScatterViewItem 自定义大小

发布于 2024-09-25 04:07:41 字数 1346 浏览 6 评论 0原文

我使用 MVVM 模式开发 Surface 应用程序。 我有不同的视图,我想将它们放入一个 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>

但它不起作用。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秉烛思 2024-10-02 04:07:41

更新:我已将此答案转换为代码项目文章:http://www.codeproject.com/KB/WPF/ScatterViewSizing.aspx - 检查以获取更多详细信息和完整的示例代码


这是非常棘手的。我不久前遇到了这个问题,并尝试了许多不同的方法 - 我什至实现了自己的 ScatterViewItem 来处理自动调整大小 - 但从未找到 100% 有效的解决方案。

我解决的解决方案是创建一个自定义控件,该控件在创建时使用附加属性来设置其父级 ScatterViewItem 的大小,该解决方案解决了获得正确的初始大小的主要问题。完整的代码太大,无法放在这里,但我将尝试解释它的核心以帮助您入门。

因此,每当我向 scatterview 添加内容(通过数据绑定)时,我的 itemtemplate 都会将 ScatterViewItem 的内容设置为名为“PopupWindow”的控件(源自 UserControl)。 PopupWindow 定义了一个名为 InitialSizeRequest 的附加属性(类型为 Size),它将在其子元素中查找。在其 Loaded 事件处理程序中,它将向上搜索可视化树以找到 ScatterViewItem,然后相应地设置其大小。

生成的可视化树将如下所示:

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

在实际内容上,它们会像这样声明其大小:

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

为了从 PopupWindow 获取实际内容,我使用了下面的代码(省略了错误检查)。这是在 PopupWindow 的 Loaded 事件中执行的:

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

希望这可以帮助您入门。如果您需要进一步的解释,请评论。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文