简体   繁体   English

LongListSelector和DataTemplateSelector

[英]LongListSelector and DataTemplateSelector

I'm using the LongListSelector to realize List or Grid display for my items. 我正在使用LongListSelector来实现我的项目的列表或网格显示。 For this, I created a DataTemplateSelector and I change the LayoutMode property at runtime. 为此,我创建了一个DataTemplateSelector,并在运行时更改了LayoutMode属性。 This is working but there seems to be an issue with the DataTemplateSelector. 这是有效的,但DataTemplateSelector似乎存在问题。 If I initially launch the page, the DataTemplateSelector is called three times for my three items. 如果我最初启动页面,则会为我的三个项目调用DataTemplateSelector三次。 When I navigate to another page (settings page to change the LayoutMode) and then back, the DataTemplateSelector is just called two items but there are still three items. 当我导航到另一个页面(更改LayoutMode的设置页面)然后返回时,DataTemplateSelector只被称为两个项目,但仍然有三个项目。

DataTemplateSelector: DataTemplateSelector:

public abstract class DataTemplateSelector : ContentControl
{
    public virtual DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        return null;
    }

    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        ContentTemplate = SelectTemplate(newContent, this);
    }
}

ItemViewModeTemplateSelector: ItemViewModeTemplateSelector:

public class ItemViewModeTemplateSelector: DataTemplateSelector
{
    public DataTemplate ListViewModeTemplate
    {
        get;
        set;
    }

    public DataTemplate GridViewModeTemplate
    {
        get;
        set;
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ViewMode viewMode = ViewMode.Grid;

        // Get ViewMode from IsolatedStorageSettings...

        switch (viewMode)
        {
            case ViewMode.Grid:
                return GridViewModeTemplate;

            case ViewMode.List:
                return ListViewModeTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

MainPage.xaml: MainPage.xaml中:

<phone:LongListSelector x:Name="ItemLongListSelector" ItemsSource="{Binding Items}" LayoutMode="Grid" GridCellSize="222,222">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <common:ItemViewModeTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
                <common:ItemViewModeTemplateSelector.GridViewModeTemplate>
                    <DataTemplate>
                        <StackPanel Margin="12,12,0,0" Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}">
                            <!-- Content -->
                        </StackPanel>
                    </DataTemplate>
                </common:ItemViewModeTemplateSelector.GridViewModeTemplate>

                <common:ItemViewModeTemplateSelector.ListViewModeTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <!-- Content -->
                        </StackPanel>
                    </DataTemplate>
                </common:ItemViewModeTemplateSelector.ListViewModeTemplate>
            </common:ItemViewModeTemplateSelector>
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

This is the display when I initially launch the page: 这是我最初启动页面时的显示:

Then I navigate to another page and then back: 然后我导航到另一个页面,然后返回:

EDIT: I prepared a sample project for this issue. 编辑:我为这个问题准备了一个示例项目。 It should run without problems. 它应该没有问题。

Project: http://sdrv.ms/1cAbVxE 项目: http//sdrv.ms/1cAbVxE

I haven't got the solution but maybe a clue for someone who will solve the problem. 我没有得到解决方案,但可能是解决问题的人的线索。
I think the problem is with LongListSelector.UpdateLayout() method - when it's fired for the first time there are no items to which LLS was bound - OnChangeMethod is called that many times as the Itemsource.Count. 我认为问题在于LongListSelector.UpdateLayout()方法 - 当它第一次被触发时,没有绑定LLS的项目 - OnChangeMethod被多次调用为Itemsource.Count。 But when we leave the page and go back - LLS is Updated and method is called ommiting the middle element. 但是当我们离开页面并返回时 - LLS被更新并且方法被称为省略中间元素。
It means it works for even number of items - OnChangeMethod is called correct number of times, But for odd number of items - it's called numer of items - 1. 这意味着它适用于偶数项目 - OnChangeMethod被称为正确的次数,但对于奇数项目 - 它被称为项目的数字 - 1。
The second thing is why it's called at all - when there are no changes. 第二件事就是为什么它被调用 - 当没有变化时。

I also add a code to work on which (very simple). 我还添加了一个代码来处理(非常简单)。

I've done something similar with my app, but allowed the user to choose the LayoutMode of LLS using an Appbar button. 我已经使用我的应用程序做了类似的事情,但允许用户使用Appbar按钮选择LLS的LayoutMode。 I basically change the LongListSelector.LayoutMode and then it's ItemTemplate in code and the LLS automatically refreshes itself. 我基本上更改了LongListSelector.LayoutMode,然后在代码中更改了ItemTemplate,LLS自动刷新。 I'm not sure if this will help, but here's my code. 我不确定这是否会有所帮助,但这是我的代码。

private void layoutModeButton_Click(object sender, EventArgs e)
    {
        ApplicationBarIconButton layoutModeButton = (ApplicationBarIconButton)ApplicationBar.Buttons[0];

        if (MainLongListSelector.LayoutMode == LongListSelectorLayoutMode.Grid)
        {
            MainLongListSelector.LayoutMode = LongListSelectorLayoutMode.List;
            MainLongListSelector.ItemTemplate = this.Resources["ListListLayout"] as DataTemplate;
            layoutModeButton.IconUri = _gridButtonUri;
            layoutModeButton.Text = "grid";
        }
        else
        {
            MainLongListSelector.LayoutMode = LongListSelectorLayoutMode.Grid;
            MainLongListSelector.ItemTemplate = this.Resources["GridListLayout"] as DataTemplate;
            layoutModeButton.IconUri = _listButtonUri;
            layoutModeButton.Text = "list";
        }
    }

You might have figured out the answer already, but just to add to the conversation: this gives me really good performance for a fairly large amount of data. 您可能已经找到了答案,但只是为了添加到对话中:这为我提供了相当大量数据的非常好的性能。 Maybe you can do something similar when navigating back to the page after changing the layout in settings? 也许你可以在更改设置中的布局后导航回页面时做类似的事情?

Here is one walk around. 这是一个散步。 (Maybe the problem will be corrected with WP 8.1 Update, along with others I've spotted working with LLS. I know - this idea is ugly, hard and so on, but maybe it will be enough for your purpose: (也许这个问题会在WP 8.1 Update中得到纠正,还有其他我发现与LLS一起工作。我知道 - 这个想法很丑陋,很难等等,但也许这对你的目的来说已经足够了:

Becouse the problem concerns 'reloading' LLS, I've forced it to initialize it every time I navigate to the page (in fact I need to initialize the whole Page - it won't work only with LLS). 因为问题关注'重新加载'LLS,我每次导航到页面时都强制它初始化它(实际上我需要初始化整个页面 - 它不能仅用于LLS)。 I've moved InitializeComponent() and buttons events and so on to OnNavigatedTo(): 我已经将InitializeComponent()和按钮事件等移动到OnNavigatedTo():

 protected override void OnNavigatedTo(NavigationEventArgs e)
  {
     base.OnNavigatedTo(e);

     this._contentLoaded = false;
     InitializeComponent();

     first.Click += first_Click;
     second.Click += second_Click;
     ItemLongListSelector.ItemsSource = Items;
  }

At least OnContentChanged() is fired that many Times its needed. 至少OnContentChanged()被解雇了许多时代所需要的。 Code you can find here . 你可以在这里找到代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM