VariableSizedWrapGrid в ItemPanelTemplate в WP8

На WP8 я хотел бы отобразить список на странице следующим образом:

введите здесь описание изображения

Я знаю, что могу легко сделать это с помощью WP8.1 и элемента управления VariableSizedWrapGrid. Но мне нужно заставить его работать на WP8.0. Поэтому я пробую набор инструментов от Kinnara: https://www.nuget.org/packages/WPtoolkit.Kinnara/, который содержит VariableSizedWrapGrid.

Я могу сделать отображение, которое хочу (см. снимок экрана), но я не могу использовать его в LongListSelector или ListBox в качестве ItemPanelTemplate.

Вот код, который я пробовал (он вдохновлен методом, который работает в Windows 8, но, к сожалению, не работает в WP8), а также из этого сообщения в блоге: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2012/09/14/windows-8-xaml-and-displaying-multiple-sized-items.aspx.

           <local:SpecificListBox x:Name="LB_Wings" ItemTemplate="{StaticResource IT_Wings}" >
                <local:SpecificListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <toolkit:VariableSizedWrapGrid ItemWidth="100" ItemHeight="100" MaximumRowsOrColumns="4"></toolkit:VariableSizedWrapGrid>
                    </ItemsPanelTemplate>
                </local:SpecificListBox.ItemsPanel>
                <local:SpecificListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                    <Setter Property="toolkit:VariableSizedWrapGrid.RowSpan"   Value="{Binding ItemSize}" />
                        <Setter Property="toolkit:VariableSizedWrapGrid.ColumnSpan"  Value="{Binding ItemSize}" />
                    </Style>
                </local:SpecificListBox.ItemContainerStyle>
            </local:SpecificListBox>

шаблон данных:

  <DataTemplate x:Key="IT_Wings">          
            <Grid Margin="0,0,12,12" >
                <Image Source="{Binding BI_List}" Stretch="UniformToFill" </Image>
            </Grid>
    </DataTemplate>

SpecificListBox — это просто класс, который наследует ListBox и переопределяет метод PrepareContainerForItemOverride:

class SpecificListBox : ListBox
{
    public SpecificListBox() { }
    protected override void PrepareContainerForItemOverride(System.Windows.DependencyObject element, object item)
    {    
        dynamic lateBoundItem = item;

        int sizeFactor = (int)lateBoundItem.ItemSize;

        element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, sizeFactor);
        element.SetValue(VariableSizedWrapGrid.RowSpanProperty, sizeFactor);  
        base.PrepareContainerForItemOverride(element, item);
    }
}

Теперь в коде позади я просто заполняю LB_Wings списком элементов (которые имеют свойство ItemSize):

LB_Wings.ItemsSource = listOfItems; //a list of items that have the ItemSize property.

К сожалению, я получаю сообщение об ошибке: «Невозможно создать экземпляр типа: SpecificListBox», когда я инициализирую свою страницу.

Думаю, я близок к решению. Может ли кто-нибудь помочь мне сделать такое отображение (что кажется естественным на WP8), но с помощью ListBox и ItemPanelTemplate?

Большое спасибо


person Thomas Salandre    schedule 19.05.2014    source источник


Ответы (1)


Все, что вам нужно сделать, это сделать SpecificListBox общедоступным классом. :)

public class SpecificListBox : ListBox

Изменить

Кроме того, вам не нужны привязки в ItemContainerStyle для SpecificListBox. Я изменил их с Horizontal/VerticalContentAlignment = Stretch, потому что мне кажется, что так будет лучше. Без этого элемент управления в DataTemplate не занимает все место для элемента. Вот измененный xaml:

<local:SpecificListBox x:Name="LB_Wings" ItemTemplate="{StaticResource IT_Wings}" >
    <local:SpecificListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <toolkit:VariableSizedWrapGrid ItemWidth="100" ItemHeight="100" MaximumRowsOrColumns="4"></toolkit:VariableSizedWrapGrid>
        </ItemsPanelTemplate>
    </local:SpecificListBox.ItemsPanel>
    <local:SpecificListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
        </Style>
    </local:SpecificListBox.ItemContainerStyle>
</local:SpecificListBox>
person yasen    schedule 22.05.2014
comment
Спасибо, но я получаю еще одну ошибку при синтаксическом анализе: не удалось присвоить свойству «System.Windows.Setter.Value» в этой строке: ‹Setter Property=toolkit:VariableSizedWrapGrid.RowSpan Value={Binding ItemSize} /› I can' не могу найти способ привязать мой itemSize к свойству этого элемента управления из инструментария... - person Thomas Salandre; 22.05.2014
comment
Ну, тебе не нужна эта привязка. Если вы используете свой SpecificListBox, значения, которые вы пытаетесь связать, будут установлены в методе PrepareContainerForItemOverride. Вы можете использовать в нем SetBinding вместо SetValue, если хотите, чтобы они были связаны. - person yasen; 22.05.2014
comment
Я не понимаю. Можете быть более конкретными ? Что я делаю неправильно в методе PrepareContainerForItemOverride? спасибо за помощь - person Thomas Salandre; 22.05.2014
comment
Я немного изменил ответ. С методом все в порядке. Проблема была в ItemContainerStyle. Я не думаю, что у вас может быть привязка в значении установщика. - person yasen; 22.05.2014
comment
Я попробовал это, у меня нет никакой ошибки, но все мои элементы отображаются с одинаковым размером. И я не вхожу в метод PrepareContainerForItemOverride. Что мне нужно сделать, чтобы вызвать метод? - person Thomas Salandre; 22.05.2014
comment
Вы уверены, что используете SpecificListBox, а не обычный ListBox? Очистить и повторно развернуть. Это должно быть хорошо - это работает для меня. - person yasen; 22.05.2014
comment
О да, я менял его столько раз, что не проверял, что забыл поставить свой SpecificListBox ! :) Большое спасибо. - person Thomas Salandre; 22.05.2014
comment
Рад, что смог помочь! :) Должен ли я получить награду? :P Или у вас есть другие вопросы, связанные с этим? - person yasen; 22.05.2014
comment
Да, конечно, но StackOverflow сказал мне, что я не могу дать вам прямо сейчас, мне нужно подождать 19 часов. Но я отдам его вам, не волнуйтесь :) Еще раз спасибо - person Thomas Salandre; 22.05.2014