4

私は、C# Windows ストア アプリでアイテムを含むリストビューを持っています (それはあなたがこれらと呼んでいるものですか?もう Metro アプリとは呼ばれていないと聞きました)。

Android のExpandableListViewと同様に、リスト項目(ボタンではなく) をタップしてそのリスト項目を展開し、展開されたリスト項目をタップして折りたたむことができるようにしたいと考えています。別のリスト項目をタップすると、現在展開されているリスト項目が崩壊し、もう一方は拡大します。

私の特定のケースDataTemplateでは、リストアイテムの展開されたビューと展開されていないビューの両方があります。Android の ExpandableListView は、 listitem をより大きな item に置き換えるのではなく、追加情報 ( WPFのExpanderはそれに似たようなことを行います) でlistitem を展開できることを見てきましたが、Windows ストア アプリでこれに対する一般的な解決策はありますか? そうでない場合、最も近いものは何ですか?

次の図のように、この方法でリストアイテムを展開できるコンポーネントがあるかどうかを知りたいです。 Windows ストア アプリでの Expandable-ListItem の描画

4

1 に答える 1

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>

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

この分離されたコードだけでこのソリューションに十分かどうかはテストしていませんが、そうであることを願っています。このコードには少なくとも重要なポイントが含まれています。遅くなりましたが、好奇心旺盛な人々のために何かを投稿したかっただけです。これがうまくいかない場合は、問題についてコメントを残してください。欠落している部分を確実に追加します。

また、ListViewItemStyleContainer の ListViewItemPresenter をいじって、選択効果などを改善しましたが、短くしておくのが最善だと思います。これも面白いと思ったら、それについてもコメントを残してください。私はそれを含めようとします.

于 2013-10-15T23:52:25.270 に答える