为什么我的UserControl的大小为零?

时间:2015-01-28 01:36:24

标签: c# xaml windows-store-apps

在布局过程中,我的用户控件似乎没有遵循Horizo​​ntalAlignment或VerticalAlignment。

我的Windows Store XAML用户控件定义如下:

<UserControl
    x:Class="IWalker.Views.PDFPageUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:IWalker.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="200"
    d:DesignWidth="250">

    <Image x:Name="ThumbImage"/>

</UserControl>

它位于ItemsControl水平列表中,如下所示(为了简洁,我将页面XAML decl放在顶部 - 但它来自Windows应用商店空白模板):

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ScrollViewer VerticalScrollMode="Disabled" HorizontalScrollMode="Auto" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
        <ItemsControl x:Name="SlideStrip">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:PDFPageUserControl Margin="0 0 5 0" Height="{Binding Path=ActualHeight, ElementName=SlideStrip, Mode=OneWay}" ViewModel="{Binding}" RespectRenderingDimension="Vertical" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>

正如您所看到的,PDFPageUserControl的高度绑定到它将要坐的ItemsControl的ActualHeight。当发生这种情况时,一切正常。如果我删除该绑定,那么我的用户控件的大小为0,0。

这是棘手的部分。 PDFPageUserControl没有隐式大小。我需要设置它的高度,宽度或两者(正如你在上面的代码snippit中看到的那样)。然后,它将使用PDF渲染代码生成正确大小的图像并显示它(所有这些都有效)。

我的理论是,Windows Store XAML的自动布局默认情况下不会尝试扩展,直到它们适合。它允许大多数控件确定自己的大小并将其报告给布局引擎。然后布局引擎围绕它们进行布局,构建起来。我的报告最初是0,0,等待被告知其高度,以便它可以通知系统其宽度,反之亦然。由于ItemsControl的StackPannel从不强制物品伸展以适应其内部,因此不会发生。

但是,很明显允许某些控件扩展以填充所有可用空间 - 例如Grid或ScrollViewer。我曾经想过&#34; Stretch&#34;水平和垂直对齐模式将在布局引擎中为您执行此操作。但这对我的UserControl似乎没有用 - 好像我没有正确参与布局过程。

有没有办法修复我的控件,以便按照Horizo​​ntalAlignment和VerticalAlignment的顺序拉伸以填充可用空间?

如果你觉得这里有一些基本的缺失信息/代码,当然要问,我会添加它。您还可以在此处查看所有代码:https://github.com/gordonwatts/IndicoWalker/tree/master/IWalker/IWalker.Windows/Views

2 个答案:

答案 0 :(得分:1)

WinRT / XAML中的

ActualHeight不可绑定 - 它不会引发更改通知,因此您应该手动更新它。考虑我对这个问题的DoubleViewModel回答:

GridView with 2 columns, fill width

答案 1 :(得分:1)

事实证明,这个特定问题的关键是参与布局引擎的过程。特别是,用户控件应覆盖MeasureOverride方法。完成后,我可以在上面的XAML中删除高度绑定。

MeasureOverride将告诉您可用的大小,这取决于VerticalAlignment和Horizo​​ntalAlignment之类的内容。取决于,一些建议的大小将是合理的数字,其他将是NaN。然后我可以计算出我的图像的大小,并将其交还。

完成后,布局引擎将调整我的UserControl的大小。我迷上了SizeChanged事件,每次看到它,我都会重新生成我的图像。结果代码很干净!

对于那些新人来说,请注意一点 - 确保准备好NaN值以获得可用的大小。