首页 文章

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

提问于
浏览
0

在布局过程中,我的用户控件似乎不遵循HorizontalAlignment或VerticalAlignment .

我有一个Windows商店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水平列表中,如下所示(为简洁起见,我将Page XAML decl放在顶部 - 但它来自Windows Store空白模板):

<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 . 我原以为水平和垂直对齐的“拉伸”模式会在布局引擎中为你做这个 . 但这对我的UserControl似乎不起作用 - 好像我没有正确参与布局过程 .

有没有办法修复我的控件,因此它会拉伸以填充HorizontalAlignment和VerticalAlignment所订购的可用空间?

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

2 回答

  • 1

    WinRT / XAML中的 ActualHeight 不会引发更改通知,因此您应该手动更新它 . 考虑一下我对这个问题的回答:

    GridView with 2 columns, fill width

  • 1

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

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

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

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

相关问题