繁体   English   中英

LongListSelector和DataTemplateSelector

[英]LongListSelector and DataTemplateSelector

我正在使用LongListSelector来实现我的项目的列表或网格显示。 为此,我创建了一个DataTemplateSelector,并在运行时更改了LayoutMode属性。 这是有效的,但DataTemplateSelector似乎存在问题。 如果我最初启动页面,则会为我的三个项目调用DataTemplateSelector三次。 当我导航到另一个页面(更改LayoutMode的设置页面)然后返回时,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:

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中:

<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>

这是我最初启动页面时的显示:

然后我导航到另一个页面,然后返回:

编辑:我为这个问题准备了一个示例项目。 它应该没有问题。

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

我没有得到解决方案,但可能是解决问题的人的线索。
我认为问题在于LongListSelector.UpdateLayout()方法 - 当它第一次被触发时,没有绑定LLS的项目 - OnChangeMethod被多次调用为Itemsource.Count。 但是当我们离开页面并返回时 - LLS被更新并且方法被称为省略中间元素。
这意味着它适用于偶数项目 - OnChangeMethod被称为正确的次数,但对于奇数项目 - 它被称为项目的数字 - 1。
第二件事就是为什么它被调用 - 当没有变化时。

我还添加了一个代码来处理(非常简单)。

我已经使用我的应用程序做了类似的事情,但允许用户使用Appbar按钮选择LLS的LayoutMode。 我基本上更改了LongListSelector.LayoutMode,然后在代码中更改了ItemTemplate,LLS自动刷新。 我不确定这是否会有所帮助,但这是我的代码。

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";
        }
    }

您可能已经找到了答案,但只是为了添加到对话中:这为我提供了相当大量数据的非常好的性能。 也许你可以在更改设置中的布局后导航回页面时做类似的事情?

这是一个散步。 (也许这个问题会在WP 8.1 Update中得到纠正,还有其他我发现与LLS一起工作。我知道 - 这个想法很丑陋,很难等等,但也许这对你的目的来说已经足够了:

因为问题关注'重新加载'LLS,我每次导航到页面时都强制它初始化它(实际上我需要初始化整个页面 - 它不能仅用于LLS)。 我已经将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;
  }

至少OnContentChanged()被解雇了许多时代所需要的。 你可以在这里找到代码。

暂无
暂无

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

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