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