Подтвердить что ты не робот

Измерение размера детей VariableSizedWrapGrid и WrapGrid

Оба VariableSizedWrapGrid и WrapGrid имеют странное измерение - они измеряют всех детей на основе первого элемента.

Из-за этого следующий 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 измеряет первый элемент, а затем остальные дети измеряются с желаемым размером первого.

Любые обходные пути?

4b9b3361

Ответ 1

Вам нужно использовать Attached Properties на каждом Rectangle VariableSizeWrapGrid.ColumnSpan и VariableSizeWrapGrid.RowSpan, а также добавить ItemHeight и ItemWidth в VariableSizeWrapGrid:

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

Ответ 2

Это может быть не самый лучший способ, но так я сделал это в своем приложении @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

Ответ 3

Чтобы использовать VariableSizeWrapGrid, вы должны создать собственный собственный элемент управления GridView и переопределить PrepareContainerForItemOverride и установить внутри этого метода элементы RowSpan и ColumnSpan. Таким образом, каждый элемент будет иметь собственную высоту/ширину.

Вот хороший учебник/прохождение Джерри Никсона: http://dotnet.dzone.com/articles/windows-8-beauty-tip-using

Ответ 4

Теперь удалось разобраться в этом. Вам нужно будет использовать VisualTreeHelperExtension.cs в инструменте WinRT XAML Toolkit (http://winrtxamltoolkit.codeplex.com). Для меня я пытался настроить ListView, который имел GridView в качестве элемента ItemsPanelTemplate, эта же концепция должна применяться для вас.

1) Прикрепите к событию LayoutUpdated вашего ListView (это когда вы захотите обновить размеры)

_myList.LayoutUpdated += _myList_LayoutUpdated;

2) Используйте VisualTreeHelperExtensions.GetDescendantsOfType(), чтобы найти общий (и уникальный) тип элемента в шаблоне данных элемента (например: текстовый блок, динамический по ширине):

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(), чтобы найти основной контейнер WrapGrid для вашего ListView:

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;