VariableSizedWrapGrid和WrapGrid的子元素大小测量

12

VariableSizedWrapGridWrapGrid都有奇怪的测量方式 - 它们基于第一个子项来测量所有子项。

因此,以下XAML代码将裁剪第三个子项。

    <VariableSizedWrapGrid Orientation="Horizontal">
        <Rectangle Width="50" Height="100" Margin="5" Fill="Blue" />
        <Rectangle Width="50" Height="50" Margin="5" Fill="Red" />
        <Rectangle Width="50" Height="150" Margin="5" Fill="Green" />
        <Rectangle Width="50" Height="50" Margin="5" Fill="Red" />
        <Rectangle Width="50" Height="100" Margin="5" Fill="Red" />
    </VariableSizedWrapGrid>

看起来VariableSizedWrapGrid会测量第一个项,然后其余的子项将使用第一个项的期望大小进行测量。

有什么变通方法吗?

4个回答

3

您需要在每个矩形变量的VariableSizeWrapGrid.ColumnSpan和VariableSizeWrapGrid.RowSpan上使用附加属性,同时为VariableSizeWrapGrid添加ItemHeight和ItemWidth:

<VariableSizedWrapGrid Orientation="Horizontal" ItemHeight="50" ItemWidth="50"> 
    <Rectangle 
        VariableSizedWrapGrid.ColumnSpan="1" 
        VariableSizedWrapGrid.RowSpan="2"
        Width="50" Height="100" Margin="5" Fill="Blue" /> 
</VariableSizedWrapGrid>

0

这可能不是最好的方法,但这就是我在我的@MetroRSSReader应用程序中所做的方式

<common:VariableGridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VariableSizedWrapGrid ItemWidth="225" 
                                           ItemHeight="{Binding ElementName=bounds, Path=Text}" 
                                           MaximumRowsOrColumns="5" Orientation="Vertical"
                                           />
                </ItemsPanelTemplate>
                </common:VariableGridView.ItemsPanel>
        </common:VariableGridView>

注意ItemHeight的值绑定到一个TextBlock。
<TextBlock x:Name="bounds" Grid.Row="1" Margin="316,8,0,33" Visibility="Collapsed"/>

这个设置在LayoutAwarePage.cs中。

public string Fix_item_height_for_current_screen_resolution()
    {
        var screenheight = CoreWindow.GetForCurrentThread().Bounds.Height;
        var itemHeight = screenheight < 1000 ? "100" : "140";

        return itemHeight;
    }

您可以浏览完整的源代码http://metrorssreader.codeplex.com/SourceControl/changeset/view/18233#265970


0
今天终于解决了这个问题。您需要使用WinRT XAML Toolkit中的VisualTreeHelperExtension.cs(http://winrtxamltoolkit.codeplex.com)。对我来说,我试图调整一个具有GridView作为其ItemsPanelTemplate的ListView,相同的概念应该适用于您。
1)附加到ListView的LayoutUpdated事件(这是您想要更新大小的时间)
_myList.LayoutUpdated += _myList_LayoutUpdated;
2)使用VisualTreeHelperExtensions.GetDescendantsOfType()在您的项数据模板中查找常见(且唯一)元素类型(例如:动态宽度的TextBlock):
var items = VisualTreeHelperExtensions.GetDescendantsOfType<TextBlock>(_myList);  

if (items == null || items.Count() == 0)
  return;

3)获取找到的项的最大宽度:

double maxWidth = items.Max(i => i.ActualWidth) + 8;

4)使用VisualTreeHelperExtensions.GetDescendantsOfType()查找ListView的主要WrapGrid容器:

var wg = _categoryList.GetDescendantsOfType<WrapGrid>();
if (wg == null || wg.Count() != 1)
  throw new InvalidOperationException("Couldn't find main ListView container");

5) 将WrapGrid的ItemWidth设置为您计算出的最大宽度:

wg.First().ItemWidth = maxWidth;


0
要使用VariableSizeWrapGrid,您应该创建自己的GridView自定义控件并覆盖PrepareContainerForItemOverride方法,在该方法中设置元素的RowSpan和ColumnSpan。这样每个元素都将拥有自己的高度/宽度。
这里有一个由Jerry Nixon提供的不错的教程/演示:http://dotnet.dzone.com/articles/windows-8-beauty-tip-using

1
有没有想法如何在模型更改时添加这样的行/列跨度以使其数据绑定并更新。PrepareContainerForItemOverride不会在更改时被调用。 - Poul K. Sørensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接