Windows应用商店应用:如何使用可扩展/可扩展的ListItems制作ListView?

Ask*_* B. 4 c# xaml listview touch windows-store-apps

我在C#Windows应用商店应用中有一个包含项目的Listview(这就是你所说的那些?我听说他们不再称为Metro Apps了).

与Android中的ExpandableListView类似,我希望能够点击该列表项目的列表项目(而非按钮)进行扩展,点击展开的列表项目以使其折叠,如果您点击另一个列表项目,则当前展开的列表项目将会崩溃,另一个将扩大.

在我的特定情况下,我有一个DataTemplate扩展和非扩展的listitems视图.我已经看到Android的ExpandableListView可以使用附加信息扩展listitem (来自WPF 的Expander做类似的事情),而不是用更大的项目替换它,但在Windows应用商店应用程序中是否有一个通用的解决方案?如果没有,最接近的等价物是什么?

如下图所示,我想知道是否有一个组件可以通过这种方式扩展listitems,或者如果没有,我有哪些替代方案: 在Windows应用商店应用中绘制Expandable-ListItem

Ask*_* B. 5

我最终得到了一个有效的解决方案,但看起来并不太花哨.DataTemplate单击项目时会切换,但没有动画:它会立即切换.

这是重要的代码部分:

XAML

<Page.Resources>
    <DataTemplate x:Key="dtSmall">
        <!--Component template for the un-expanded listitems-->
    </DataTemplate>
    <DataTemplate x:Key="dtEnlarged">
        <!--Component template for the expanded listitems-->
    </DataTemplate>
</Page.Resources>
<Grid>
    <ListView x:Name="lvEnlargeable"
        IsItemClickEnabled="True"
        ItemTemplate="{StaticResource dtSmall}"
        ItemsSource="{Binding ...}"
        SelectionChanged="LVEnlargeable_SelectionChanged"
        ItemClick="LVEnlargeable_ItemClick"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

XAML.CS

public sealed partial class MainPage : Page
{
    private DataTemplate dtSmall;
    private DataTemplate dtEnlarged;

    public MainPage()
    {
        this.InitializeComponent();
        dtSmall = (DataTemplate)Resources["dtSmall"];
        dtEnlarged = (DataTemplate)Resources["dtEnlarged"];
    }

    // A selected item is treated as an expanded/enlarged item
    private void LVEnlargeable_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        /* First we set all the items that has been deselected
        to be collapsed, aka. using the dtSmall DataTemplate.
        We expect 0 or 1 item to have been deselected
        but handle all cases easily with a foreach loop.
        */
        foreach (var item in e.RemovedItems)
        {
            // Set the DataTemplate of the deselected ListViewItems
            ((ListViewItem)(sender as ListView).ContainerFromItem(item)).ContentTemplate = dtSmall;
        }

        /* Then we set all the items that has been selected
        to be expanded.
        We should probably throw an Exception if more than 1 was found,
        because it's unwanted behavior, but we'll ignore that for now.
        */
        foreach (var item in e.AddedItems)
        {
            ((ListViewItem)(sender as ListView).ContainerFromItem(e.AddedItems[0])).ContentTemplate = dtEnlarged;
        }
    }

    /* We need click events because SelectionChanged-events
    cannot detect clicks on an already selected item */
    private void LVEnlargeable_ItemClick(object sender, ItemClickEventArgs e)
    {
        ListView lv = (sender as ListView);

        /* Having set the IsItemClickEnabled property on the ListView to True
        we have to handle selection events manually.
        If nothing is selected when this click occurs, then select this item*/
        if (lv.SelectedItem == null)
        {
            lv.SelectedItem = e.ClickedItem;
        }
        else
        {
            // Clicking on an expanded/selected/enlarged item will deselect it
            if (lv.SelectedItem.Equals(e.ClickedItem))
            {
                lv.SelectedItem = null;
            }
            else
            {   /* If it's not a selected item, then select it
                    (and let SelectionChanged unselect the already selected item) */
                lv.SelectedItem = e.ClickedItem;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有测试过这个孤立的代码本身对于这个解决方案是否足够,但我希望它是,并且这段代码至少包含关键点.现在已经很晚了,我只是想为有点好奇心的人发布一些东西.如果这显示不适合您,那么请留下关于该问题的评论,我将确保添加缺少的部分.

我也搞砸了ListViewItemStyleContainer的ListViewItemPresenter以获得更好的选择效果等等,但我认为最好保持简短.如果你发现这个也很有趣,那么也可以随意发表评论,我会试着把它包括在内.