我可以在另一个 ListView 的 HeaderItem 中添加 ListView 或 GridView 吗? [UWP]
Can I add a ListView or a GridView inside HeaderItem of another ListView? [UWP]
我有以下场景。
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}/>
现在整个东西都需要滚动,所以我可以像这样将它们放在 ScrollViewer 中,
<ScrollViewer>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}/>
</ScrollViewer>
但显然这样做会破坏 ListView
的虚拟化,所以我没有这样做,而是试图将 GridView
和 TextBlock
放在 ListViewHeaderItem
中。这样我就可以在不使用单独的scrollviewer的情况下使用listview本身的scrollviewer,从而使虚拟化生效。
所以,我的问题是我可以在列表的 headerItem 中放置一个带有不同 itemsSource 的 gridView 吗?到目前为止,我无法做到,因为 HeaderItem 的数据上下文似乎是列表视图的 ItemsSource 的数据上下文。我尝试了以下方法。
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}>
<ListView.HeaderTemplate>
<DataTemplate>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
</DataTemplate>
</ListView.HeaderTemplate>
</ListView>
感谢阅读。
您的代码不是我可以轻松测试的格式,但通常有两种方法可以做到这一点:
1) 给父 window 一个名字,例如'x:Name=_this',然后将您的 GridView 绑定更改为 ItemsSource={Binding X, ElementName=_this}
。
2) 使用 DataProxy(有关代码和说明,请参阅 this article)并将您的 GridView 绑定更改为 ItemsSource={Binding Data.X, Source={StaticResource proxy}}
。
根据我的经验,他们都使用 WPF,但只有第二个使用 Xamarin。我自己不必使用 UWP 执行此操作,但您可能会发现其中至少有一个有效。
如果您希望 HeaderTemplate 内容具有与父列表不同的 DataContext,您可以使用 ListView.Header 属性:
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P} Header={Binding HDC}>
<ListView.HeaderTemplate>
<DataTemplate>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
</DataTemplate>
</ListView.HeaderTemplate>
</ListView>
其中列表的DataContext是这样的:
public class ListDataContext {
public IEnumerable K {get;}
public HeaderDataContext HDC {get;}
public class HeaderDataContext {
public IEnumerable X {get;}
public string Z {get;}
}
}
我有以下场景。
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}/>
现在整个东西都需要滚动,所以我可以像这样将它们放在 ScrollViewer 中,
<ScrollViewer>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}/>
</ScrollViewer>
但显然这样做会破坏 ListView
的虚拟化,所以我没有这样做,而是试图将 GridView
和 TextBlock
放在 ListViewHeaderItem
中。这样我就可以在不使用单独的scrollviewer的情况下使用listview本身的scrollviewer,从而使虚拟化生效。
所以,我的问题是我可以在列表的 headerItem 中放置一个带有不同 itemsSource 的 gridView 吗?到目前为止,我无法做到,因为 HeaderItem 的数据上下文似乎是列表视图的 ItemsSource 的数据上下文。我尝试了以下方法。
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P}>
<ListView.HeaderTemplate>
<DataTemplate>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
</DataTemplate>
</ListView.HeaderTemplate>
</ListView>
感谢阅读。
您的代码不是我可以轻松测试的格式,但通常有两种方法可以做到这一点:
1) 给父 window 一个名字,例如'x:Name=_this',然后将您的 GridView 绑定更改为 ItemsSource={Binding X, ElementName=_this}
。
2) 使用 DataProxy(有关代码和说明,请参阅 this article)并将您的 GridView 绑定更改为 ItemsSource={Binding Data.X, Source={StaticResource proxy}}
。
根据我的经验,他们都使用 WPF,但只有第二个使用 Xamarin。我自己不必使用 UWP 执行此操作,但您可能会发现其中至少有一个有效。
如果您希望 HeaderTemplate 内容具有与父列表不同的 DataContext,您可以使用 ListView.Header 属性:
<ListView ItemsSource={Binding K} ItemsTemplate={StaticResource P} Header={Binding HDC}>
<ListView.HeaderTemplate>
<DataTemplate>
<GridView ItemsSource={Binding X} ItemsTemplate={StaticResource Y}/>
<TextBlock Text={Binding Z} />
</DataTemplate>
</ListView.HeaderTemplate>
</ListView>
其中列表的DataContext是这样的:
public class ListDataContext {
public IEnumerable K {get;}
public HeaderDataContext HDC {get;}
public class HeaderDataContext {
public IEnumerable X {get;}
public string Z {get;}
}
}