我正在使用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>
这是我最初启动页面时的显示:
然后我导航到另一个页面,然后返回:
编辑:我为这个问题准备了一个示例项目。它应该没有问题。
答案 0 :(得分:4)
我没有得到解决方案,但可能是解决问题的人的线索
我认为问题在于LongListSelector.UpdateLayout()方法 - 当它第一次被触发时,没有绑定LLS的项目 - OnChangeMethod被多次调用为Itemsource.Count。但是当我们离开页面并返回时 - LLS被更新并且方法被称为省略中间元素
这意味着它适用于偶数项目 - OnChangeMethod被称为正确的次数,但对于奇数项目 - 它被称为项目的数字 - 1.
第二件事就是为什么它被召唤 - 当没有变化时
我还添加了一个code来处理(非常简单)。
答案 1 :(得分:3)
我已经使用我的应用做了类似的事情,但允许用户使用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";
}
}
你可能已经找到了答案,但只是为了添加到对话中:这给了我相当大量数据的非常好的表现。也许你可以在更改设置中的布局后导航回页面时做类似的事情吗?
答案 2 :(得分:1)
这是一个走动。 (也许这个问题将在WP 8.1更新中得到纠正,同时others我发现我正在使用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()会被触发,需要很多次。您可以找到代码here。